package cc.rengu.igas.momp.core.service.trans;

import cc.rengu.igas.momp.common.constant.CommonConstant;
import cc.rengu.igas.momp.common.dao.*;
import cc.rengu.igas.momp.common.dao.impl.*;
import cc.rengu.igas.momp.common.entity.*;
import cc.rengu.igas.momp.common.enums.*;
import cc.rengu.igas.momp.common.util.MompDateUtil;
import cc.rengu.igas.momp.facade.bean.MchntFeeDiscountMcStatInfoBean;
import cc.rengu.igas.momp.facade.bean.MchntFeeDiscountMcTxnStatInfoBean;
import cc.rengu.igas.momp.facade.bean.MchntFeeDiscountMchntStatInfoBean;
import cc.rengu.igas.momp.facade.request.QueryMchnFeeDiscountDetailRequest;
import cc.rengu.igas.momp.facade.response.QueryMchnFeeDiscountDetailResponse;
import cc.rengu.oltp.service.base.RadpService;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.entity.SysParam;
import cc.rengu.oltp.service.common.enums.ChannelEnum;
import cc.rengu.oltp.service.common.enums.OltpRpcdEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.utility.util.AmountUtil;
import cc.rengu.oltp.utility.util.ConvertUtil;
import cc.rengu.oltp.utility.util.DateUtil;
import cc.rengu.oltp.utility.util.XmlTreeUtil;
import cc.rengu.utility.base.StringUtil;
import com.alibaba.fastjson.JSON;

import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author : liujinan
 * @version 1.0.0
 * @date 2020/4/7
 * @Description: 手续费减免商户统计报表查询功能实现
 */
public class MchntFeeDiscountDetailService extends RadpService {
    //营销活动表json字符串
    private String initStatData;
    private String globalInstId;
    private String globalTraceNo;
    private String globalTxnDate;
    private String globalTxnTime;
    /**
     * 新商户入驻时间是否区分15号之前还是之后
     */
    private static final String MOMP_DISTINGUISH_MIDDLE_OF_MONTH = "MOMP_DISTINGUISH_MIDDLE_OF_MONTH";
    /**
     * 东营行机构代码
     */
    private static final String INST_ID_DY = "812";
    /**
     * 东营行新商户重复入网校验手续费优惠额度
     */
    private static final String DISCOUNT_AMOUNT = "40";

    @Override
    protected int bizInit(String s) {
        return 0;
    }

    @Override
    protected int bizProcess(String s, int i) {

        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();

        try {
            QueryMchnFeeDiscountDetailRequest queryMchnFeeDiscountDetailRequest = new QueryMchnFeeDiscountDetailRequest();
            ConvertUtil.convertOutput(queryMchnFeeDiscountDetailRequest);

            QueryMchnFeeDiscountDetailResponse queryMchnFeeDiscountDetailResponse = new QueryMchnFeeDiscountDetailResponse();
            queryMchnFeeDiscountDetailResponse.setHeader(queryMchnFeeDiscountDetailRequest.getHeader());
            BizResponse<QueryMchnFeeDiscountDetailResponse> bizResponse = new BizResponse<>();
            bizResponse.setResult(queryMchnFeeDiscountDetailResponse);

            globalInstId = queryMchnFeeDiscountDetailRequest.getHeader().getInstId();
            globalTraceNo = queryMchnFeeDiscountDetailRequest.getHeader().getTraceNo();
            globalTxnDate = queryMchnFeeDiscountDetailRequest.getHeader().getTransDate();
            globalTxnTime = queryMchnFeeDiscountDetailRequest.getHeader().getTransTime();

            // 服务调用
            BizResponse<QueryMchnFeeDiscountDetailResponse> bizResponseNew = mchntFeeDiscountDetail(xmlTreeUtil, queryMchnFeeDiscountDetailRequest, queryMchnFeeDiscountDetailResponse);

            ConvertUtil.convertInput(bizResponseNew.getResult());

        } catch (BizException e) {
            try {
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_CODE, e.getCode());
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_DESC, e.getMessage());
                xmlTreeUtil.setXmlTreeStringValue(CommonConstant.KEY_RESPDESC, e.getMessage());
            } catch (Exception e1) {
                rglog.error(StringUtil.ExceptionToString(e1));
            }
        } catch (Exception e) {
            rglog.error(StringUtil.ExceptionToString(e));
            try {
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_CODE, OltpRpcdEnum.OLTP_PROCESS_ERROR.getRespCode());
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_DESC, OltpRpcdEnum.OLTP_PROCESS_ERROR.getRespDesc());
                xmlTreeUtil.setXmlTreeStringValue(CommonConstant.KEY_RESPDESC, e.getMessage());
            } catch (Exception e1) {
                rglog.error(StringUtil.ExceptionToString(e));
            }
        }

        return CommonConstant.PROCESS_SUCCESS;
    }

    @Override
    protected int bizTerminate(String s) {
        return 0;
    }

    private BizResponse<QueryMchnFeeDiscountDetailResponse> mchntFeeDiscountDetail(XmlTreeUtil xmlTreeUtil, QueryMchnFeeDiscountDetailRequest queryMchnFeeDiscountDetailRequest, QueryMchnFeeDiscountDetailResponse queryMchnFeeDiscountDetailResponse) throws Exception {

        BizResponse<QueryMchnFeeDiscountDetailResponse> bizResponse = new BizResponse<>();

        rglog.info("交易流水号 TXN_NUM = {}", queryMchnFeeDiscountDetailRequest.getHeader().getTxnNum());

        List<MchntFeeDiscountMcStatInfoBean> allMchntFeeDiscountMcStatInfoList = new ArrayList<>();

        //获取商户信息
        for (MchntFeeDiscountMchntStatInfoBean mchntFeeDiscountMchntStatInfoBean : queryMchnFeeDiscountDetailRequest.getMchntInfoList()) {
            TBMchntBaseInfo mchntBaseInfo = getMchntBaseInfo(queryMchnFeeDiscountDetailRequest, mchntFeeDiscountMchntStatInfoBean.getMchntNo());
            if (null != mchntBaseInfo) {
                boolean isUseChainMchntMc = false;
                String instId = mchntBaseInfo.getInstId();
                String mchntNo = mchntBaseInfo.getMchntNo();
                String mchntArea = mchntBaseInfo.getMchntArea();
                //商户性质
                String mchntType = mchntBaseInfo.getMchntType();
                //独立营销活动标识
                String idpdCmavyFlg = mchntBaseInfo.getMarketFlag();
                //连锁商户号
                String chainMchntNo = mchntBaseInfo.getChainMchntNo();
                //是否独立维护商户资料
                String independentDataFlag = mchntBaseInfo.getIndependentDataFlag();
                TBMchntBaseInfo chainMchntBaseInfo = new TBMchntBaseInfo();
                if (CommonConstant.YES.equals(independentDataFlag) && MchntTypeEnum.CHAIN_MCHNT_STORE.getMchntType().equals(mchntType) && CommonConstant.ZERO_COMMON_CONSTANT.equals(idpdCmavyFlg)
                        || CommonConstant.NO.equals(independentDataFlag)) {
                    MchntInfoMapper mchntInfoMapper = new MchntInfoMapperImpl();
                    chainMchntBaseInfo = mchntInfoMapper.selectMompMchntBaseInfoByPrimaryKey(instId, chainMchntNo);
                    if (null == chainMchntBaseInfo) {
                        //查询不到商户信息，流程结束
                        rglog.error("查询商户基本信息信息失败, INST_ID=<{}>, MCHNT_NO=<{}>", mchntBaseInfo.getSignInstId(), mchntBaseInfo.getMchntNo());
                        throw new BizException(RespCodeEnum.GET_MCHNT_BASE_INFO_ERROR.getRespCode(), RespCodeEnum.GET_MCHNT_BASE_INFO_ERROR.getRespDesc());
                    }
                    mchntNo = chainMchntBaseInfo.getMchntNo();
                    mchntArea = chainMchntBaseInfo.getMchntArea();
                    isUseChainMchntMc = true;
                    rglog.info("商户<{}> 商户类型为11:连锁商户门店，商户独立营销活动标识为<{}> 是否独立维护商户资料<{}> 计算营销时根据上级商户<{}> 获取营销活动计算!", mchntBaseInfo.getMchntNo(), idpdCmavyFlg, independentDataFlag, chainMchntNo);
                } else {
                    rglog.info("商户<{}> 是否独立维护商户资料<{}> 商户类型为<{}> 无需判断独立营销活动标识，均使用当前商户号计算的营销！", mchntBaseInfo.getMchntNo(), independentDataFlag, mchntType);
                }

                //查询商户手续费减免营销活动信息
                //当前商户下所有营销活动List
                List<StatisticsStatementQueryRespInfo> mcNOList = new ArrayList<>();

                if (isUseChainMchntMc) {
                    getAllMcListInfo(queryMchnFeeDiscountDetailRequest, mcNOList, chainMchntBaseInfo);
                } else {
                    getAllMcListInfo(queryMchnFeeDiscountDetailRequest, mcNOList, mchntBaseInfo);
                }

                if (mcNOList.isEmpty()) {
                    rglog.error("机构<{}> 商户<{}> 商圈<{}> 未查询到营销活动信息!", globalInstId, mchntNo, mchntArea);
                    continue;
                } else {
                    //循环遍历上步查询到的营销活动编号
                    for (StatisticsStatementQueryRespInfo feeDiscount : mcNOList) {
                        if (!StringUtil.isNullorEmpty(feeDiscount.getInitStatData())) {
                            initStatData = feeDiscount.getInitStatData();
                        }

                        List<TMStatMfdMchnt> statFeeMchntList = new ArrayList<>();
                        //查询商户手续费减免活动统计信息
                        getMchntFeeDiscountStaticInfo(feeDiscount, mchntNo, statFeeMchntList);

                        //如果商户手续费减免活动统计表数据查询不为空
                        if (!statFeeMchntList.isEmpty()) {
                            //将表数据转换为响应实体对象
                            List<MchntFeeDiscountMcStatInfoBean> mchntFeeDiscountMcStatInfoBeanList = convertStatFeeMchntInfoBean(statFeeMchntList, feeDiscount.getFeeLimit());

                            //循环遍历商户手续费减免活动统计信息
                            for (MchntFeeDiscountMcStatInfoBean mchntFeeDiscountMcStatInfoBean : mchntFeeDiscountMcStatInfoBeanList) {
                                List<TMStatMfdMchntDay> StatToClientMchntDayList = new ArrayList<>();
                                //查询商户手续费减免活动单日统计信息
                                getMchntFeeDiscountDayInfo(queryMchnFeeDiscountDetailRequest, feeDiscount.getMcNo(), mchntNo, StatToClientMchntDayList);
                                if (!StatToClientMchntDayList.isEmpty()) {
                                    //将表数据转换为响应实体对象
                                    List<MchntFeeDiscountMcTxnStatInfoBean> mchntFeeDiscountMcTxnStatInfoBeanList = StatToClientMchntDayList.stream().map(this::convertStatFeeMchntDayInfoBean).collect(Collectors.toList());
                                    mchntFeeDiscountMcStatInfoBean.setTxnStatInfoList(mchntFeeDiscountMcTxnStatInfoBeanList);
                                }
                                mchntFeeDiscountMcStatInfoBean.setMchntNo(mchntFeeDiscountMchntStatInfoBean.getMchntNo());
                                //将营销活动统计信息添加到汇总
                                allMchntFeeDiscountMcStatInfoList.add(mchntFeeDiscountMcStatInfoBean);
                            }
                        }
                    }
                }
            } else {
                rglog.error("机构<{}> 商户<{}> 未查询到商户信息!", globalInstId, mchntFeeDiscountMchntStatInfoBean.getMchntNo());
                //未查询到商户信息流程继续
                break;
            }
        }
        //如果汇总链表记录为空
        if (allMchntFeeDiscountMcStatInfoList.isEmpty()) {
            queryMchnFeeDiscountDetailResponse.setTotalRows(CommonConstant.ZERO_COMMON_CONSTANT);
            queryMchnFeeDiscountDetailResponse.setTotalPage(CommonConstant.ZERO_COMMON_CONSTANT);
        } else {

            queryMchnFeeDiscountDetailResponse.setTotalRows(String.valueOf(allMchntFeeDiscountMcStatInfoList.size()));
            if (queryMchnFeeDiscountDetailRequest.getPageIndex().equals("-1") || queryMchnFeeDiscountDetailRequest.getPageSize().equals("-1")) {
                queryMchnFeeDiscountDetailResponse.setTotalPage(CommonConstant.ONE_COMMON_CONSTANT);
                queryMchnFeeDiscountDetailResponse.setPageIndex(CommonConstant.ONE_COMMON_CONSTANT);
                queryMchnFeeDiscountDetailResponse.setPageSize(String.valueOf(allMchntFeeDiscountMcStatInfoList.size()));
                //查询到的链表信息
                queryMchnFeeDiscountDetailResponse.setMcStatInfoList(allMchntFeeDiscountMcStatInfoList);
            } else {
                if (0 == (allMchntFeeDiscountMcStatInfoList.size() % Integer.parseInt(queryMchnFeeDiscountDetailRequest.getPageSize()))) {
                    queryMchnFeeDiscountDetailResponse.setTotalPage(String.valueOf(allMchntFeeDiscountMcStatInfoList.size() / Math.abs(Integer.parseInt(queryMchnFeeDiscountDetailRequest.getPageSize()))));
                } else {
                    queryMchnFeeDiscountDetailResponse.setTotalPage(String.valueOf(allMchntFeeDiscountMcStatInfoList.size() / Math.abs(Integer.parseInt(queryMchnFeeDiscountDetailRequest.getPageSize())) + 1));
                }

                queryMchnFeeDiscountDetailResponse.setPageIndex(queryMchnFeeDiscountDetailRequest.getPageIndex());
                queryMchnFeeDiscountDetailResponse.setPageSize(queryMchnFeeDiscountDetailRequest.getPageSize());
                //按照分页返回查询到的数据
                int fromIndex = (Integer.parseInt(queryMchnFeeDiscountDetailRequest.getPageIndex()) - 1) * Integer.parseInt(queryMchnFeeDiscountDetailRequest.getPageSize());
                int endIndex = fromIndex + Integer.parseInt(queryMchnFeeDiscountDetailRequest.getPageSize());
                if (fromIndex < allMchntFeeDiscountMcStatInfoList.size()) {
                    List<MchntFeeDiscountMcStatInfoBean> subMcMoneyOffInfoList = allMchntFeeDiscountMcStatInfoList.subList(fromIndex, (endIndex > allMchntFeeDiscountMcStatInfoList.size()) ? allMchntFeeDiscountMcStatInfoList.size() : endIndex);
                    queryMchnFeeDiscountDetailResponse.setMcStatInfoList(subMcMoneyOffInfoList);
                } else {
                    rglog.error("查询商户对客营销活动统计信息超出可查询的最大范围！");
                    throw new BizException(RespCodeEnum.GET_MCSTAT_INFO_ERROR.getRespCode(), RespCodeEnum.GET_MCSTAT_INFO_ERROR.getRespDesc());
                }
            }
        }

        bizResponse.setRspSysId(ChannelEnum.MOMP.getChannelType());
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());

        queryMchnFeeDiscountDetailResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        queryMchnFeeDiscountDetailResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        bizResponse.setResult(queryMchnFeeDiscountDetailResponse);

        return bizResponse;
    }

    /**
     * @param queryMchnFeeDiscountDetailRequest
     * @return void
     * @throws Exception 异常信息
     * @author liujinan
     * @date 2020/4/7
     * @Description: 查询商户基本信息
     */
    private TBMchntBaseInfo getMchntBaseInfo(QueryMchnFeeDiscountDetailRequest queryMchnFeeDiscountDetailRequest, String mchntNo) throws Exception {

        MchntInfoMapper mchntInfoMapper = new MchntInfoMapperImpl();
        return mchntInfoMapper.selectMompMchntBaseInfoByPrimaryKey(queryMchnFeeDiscountDetailRequest.getHeader().getInstId(), mchntNo);
    }

    /**
     * @param queryMchnFeeDiscountDetailRequest
     * @param mcNOList
     * @return void
     * @throws Exception 异常信息
     * @author liujinan
     * @date 2020/4/2
     * @Description: 查询商户手续费减免活动信息
     */
    private void getAllMcListInfo(QueryMchnFeeDiscountDetailRequest queryMchnFeeDiscountDetailRequest, List<StatisticsStatementQueryRespInfo> mcNOList, TBMchntBaseInfo mchntBaseInfo) {

        try {
            StatisticsStatementInfoMapper statisticsStatementInfoMapper = new StatisticsStatementInfoMapperImpl();
            //获取营销活动商户信息表中商户参与的营销活动
            List<StatisticsStatementQueryRespInfo> objectList = statisticsStatementInfoMapper.selectStatFeeMchntMcListInfo(globalInstId,
                    mchntBaseInfo.getMchntNo(), mchntBaseInfo.getMchntArea(), globalTxnDate);
            //通过达标统计表筛选商户当前参与的营销活动
            List<StatisticsStatementQueryRespInfo> resultRespMcList = new ArrayList<>();
            if (null != objectList && objectList.size() != 0) {
                //查询商户作为存量商户参加的营销活动
                rglog.info("机构<{}> 商户<{}> 商圈<{}> 查询到参加的存量（新增）商户营销活动，继续判断达标统计表数据", globalInstId, mchntBaseInfo.getMchntNo(), mchntBaseInfo.getMchntArea());
                //如果营销活动商户信息表中获取到多个手续费的活动，则继续查询达标统计表，获取当前正在使用的的唯一的商户手续费营销活动
                TMStatMfdCriteriaMapper tmStatMfdCriteriaMapper = new TMStatMfdCriteriaMapperImpl();

                for (StatisticsStatementQueryRespInfo statisticsStatementQueryRespInfo : objectList) {
                    String mcNo = statisticsStatementQueryRespInfo.getMcNo();
                    TMStatMfdCriteria tmStatMfdCriteria = tmStatMfdCriteriaMapper.selectTMStatMfdCriteriaByUsingMchntNoAndMcNoAndDateRange(globalInstId, mchntBaseInfo.getMchntNo(), globalTxnDate, mcNo);
                    if (null != tmStatMfdCriteria) {
                        String criteriaFlag = tmStatMfdCriteria.getCriteriaFlag();
                        String newMchntFlag = tmStatMfdCriteria.getNewMchntFlag();
                        String mrctDisUpLmtVal = tmStatMfdCriteria.getMrctDisUpLmtVal();

                        statisticsStatementQueryRespInfo.setNewMchntFlag(newMchntFlag);
                        statisticsStatementQueryRespInfo.setMrctDisUpLmtVal(mrctDisUpLmtVal);
                        statisticsStatementQueryRespInfo.setPeriodStartDate(tmStatMfdCriteria.getPeriodStartDate());
                        rglog.info("机构<{}> 商户<{}> 营销活动<{}> 达标状态<{}> ,商户新增标志<{}>", globalInstId, mchntBaseInfo.getMchntNo(), mcNo, criteriaFlag, newMchntFlag);
                        if ((CommonConstant.MCHNT_OLD_FLAG.equals(newMchntFlag) && CommonConstant.CRITERIA_FLAG_SET.equals(criteriaFlag)
                                || CommonConstant.MCHNT_NEW_FLAG.equals(newMchntFlag))) {
                            rglog.info("机构<{}> 商户<{}> 商户所属商圈<{}> 营销活动<{}>在当前日期时已达标", globalInstId, mchntBaseInfo.getMchntNo(), mchntBaseInfo.getMchntArea(), mcNo);
                            resultRespMcList.add(statisticsStatementQueryRespInfo);
                            break;
                        }
                    }
                }

                if (resultRespMcList.isEmpty()) {
                    //营销活动商户信息表能查到商户参加的营销活动信息，但是达标统计表没有，此时，可能存在限制了商圈的新商户营销活动，继续判断是否是新商户参加的营销活动
                    StatisticsStatementQueryRespInfo statisticsStatementQueryRespInfo = judgeIsExitNewMchntMc(queryMchnFeeDiscountDetailRequest, mchntBaseInfo);
                    if (null != statisticsStatementQueryRespInfo) {
                        mcNOList.add(statisticsStatementQueryRespInfo);
                    }
                } else {
                    mcNOList.addAll(resultRespMcList);
                }
            } else {
                //商户信息表无数据的时候，在判断是否有支持新增的营销活动之前先判断达标统计表中是否有商户的达标数据，如果有，则为新增商户的数据，直接使用
                TMStatMfdCriteriaMapper tmStatMfdCriteriaMapper = new TMStatMfdCriteriaMapperImpl();
                TMStatMfdCriteria tmStatMfdCriteria = tmStatMfdCriteriaMapper.selectTMStatMfdCriteriaByUsingMchntNoAndDateRange(globalInstId, mchntBaseInfo.getMchntNo(), globalTxnDate);
                if (null != tmStatMfdCriteria) {
                    //获取营销活动基本信息
                    rglog.info("机构<{}>的商户<{}>，开始获取营销活动<{}>的基本信息", globalInstId, tmStatMfdCriteria.getMchntNo(), tmStatMfdCriteria.getMcNo());
                    TMMcMchntFeeDiscountInfo tmMcMchntFeeDiscountInfo = getMchntFeeDiscountMcInfo(globalInstId, tmStatMfdCriteria.getMcNo());
                    if (null == tmMcMchntFeeDiscountInfo) {
                        rglog.error("机构<{}>的商户<{}>未获取到商户手续费优惠营销活动信息!", globalInstId, tmStatMfdCriteria.getMcNo());
                        throw new BizException(RespCodeEnum.GET_MCHNT_FEE_DISCOUNT_MC_LIST_ERROR.getRespCode(), RespCodeEnum.GET_MCHNT_FEE_DISCOUNT_MC_LIST_ERROR.getRespDesc());
                    }

                    String criteriaFlag = tmStatMfdCriteria.getCriteriaFlag();
                    String newMchntFlag = tmStatMfdCriteria.getNewMchntFlag();
                    String mrctDisUpLmtVal = tmStatMfdCriteria.getMrctDisUpLmtVal();
                    rglog.info("机构<{}> 商户<{}> 营销活动<{}> 达标状态<{}> ,商户新增标志<{}>(由于商户信息表未查到数据，当前在达标统计表能够查询到，则商户必为新增商户1，如不是，则有异常！)",
                            globalInstId, mchntBaseInfo.getMchntNo(), tmStatMfdCriteria.getMcNo(), criteriaFlag, newMchntFlag);
                    StatisticsStatementQueryRespInfo statisticsStatementQueryRespInfo = new StatisticsStatementQueryRespInfo();
                    statisticsStatementQueryRespInfo.setMcNo(tmStatMfdCriteria.getMcNo());
                    statisticsStatementQueryRespInfo.setFeeLimit(tmMcMchntFeeDiscountInfo.getNewMchntAmountLimit());
                    statisticsStatementQueryRespInfo.setNewMchntFlag(newMchntFlag);
                    statisticsStatementQueryRespInfo.setInitStatData(tmMcMchntFeeDiscountInfo.getInitStatData());
                    statisticsStatementQueryRespInfo.setPeriodStartDate(tmStatMfdCriteria.getPeriodStartDate());
                    if (null != mrctDisUpLmtVal && !"".equals(mrctDisUpLmtVal)) {
                        statisticsStatementQueryRespInfo.setMrctDisUpLmtVal(mrctDisUpLmtVal);
                    } else {
                        statisticsStatementQueryRespInfo.setMrctDisUpLmtVal(tmMcMchntFeeDiscountInfo.getNewMchntAmountLimit());
                    }

                    mcNOList.add(statisticsStatementQueryRespInfo);
                } else {
                    rglog.info("机构<{}> 商户<{}> 商圈<{}> 未查询到参加的存量商户的营销活动，继续判断存在入驻期间有对于新商户开展的活动", globalInstId, mchntBaseInfo.getMchntNo(), mchntBaseInfo.getMchntArea());
                    //营销活动商户信息表查询不到商户参加的营销活动信息，判断是否是有新商户参加的营销活动
                    StatisticsStatementQueryRespInfo statisticsStatementQueryRespInfo = judgeIsExitNewMchntMc(queryMchnFeeDiscountDetailRequest, mchntBaseInfo);
                    if (null != statisticsStatementQueryRespInfo) {
                        mcNOList.add(statisticsStatementQueryRespInfo);
                    }
                }
            }
        } catch (Exception e) {
            rglog.info("机构<{}> 商户<{}> 商圈<{}> 获取商户手续费减免活动列表信息失败", globalInstId, mchntBaseInfo.getMchntNo(), mchntBaseInfo.getMchntArea());
            throw new BizException(RespCodeEnum.GET_MCHNT_FEE_DISCOUNT_MC_LIST_ERROR.getRespCode(), RespCodeEnum.GET_MCHNT_FEE_DISCOUNT_MC_LIST_ERROR.getRespDesc());
        }
    }

    /**
     * @param statFeeMchntList
     * @return void
     * @throws Exception 异常信息
     * @author liujinan
     * @date 2020/4/7
     * @Description: 查询商户手续费优惠统计信息
     */
    private void getMchntFeeDiscountStaticInfo(StatisticsStatementQueryRespInfo feeDiscount, String mchntNo, List<TMStatMfdMchnt> statFeeMchntList) throws Exception {

        String mcNo = feeDiscount.getMcNo();
        String periodStartDate = feeDiscount.getPeriodStartDate();
        //获取营销活动基本信息
        rglog.info("机构<{}>的商户<{}>，开始获取营销活动<{}>的基本信息", globalInstId, mchntNo, mcNo);
        TMMcMchntFeeDiscountInfo tmMcMchntFeeDiscountInfo = getMchntFeeDiscountMcInfo(globalInstId, mcNo);
        if (null == tmMcMchntFeeDiscountInfo) {
            rglog.error("机构<{}>的商户<{}>未获取到商户手续费优惠营销活动信息!", globalInstId, mchntNo);
            throw new BizException(RespCodeEnum.GET_MCHNT_FEE_DISCOUNT_MC_LIST_ERROR.getRespCode(), RespCodeEnum.GET_MCHNT_FEE_DISCOUNT_MC_LIST_ERROR.getRespDesc());
        }
        /* 增加活动状态判断 */
        String status = tmMcMchntFeeDiscountInfo.getMcStatus();
        if (McStatusEnum.NOT_PUBLISHED.getMcStatusCode().equals(status)) {
            rglog.error("机构<{}>的商户<{}>活动<{}>状态为未发布，无优惠信息!", globalInstId, mchntNo, mcNo);
            return;
        }

        String newmrctFreeLmtTyp = tmMcMchntFeeDiscountInfo.getNewmrctFreeLmtTyp();
        //判断活动是否配置单个商户退出
        /* 需要判断优惠退出条件 */
        String statPeriod = tmMcMchntFeeDiscountInfo.getStatPeriod();
        if (CommonConstant.FEE_EXIT_MC.equals(statPeriod) || CommonConstant.FEE_EXIT_MONTH.equals(statPeriod) ||
                CommonConstant.FEE_EXIT_QUARTER.equals(statPeriod) || CommonConstant.FEE_EXIT_ANNUAL.equals(statPeriod)) {
            rglog.info("法人机构<{}> 手续费优惠营销活动<{}>设置了单个商户退出条件", globalInstId, mcNo, mchntNo);
            /* 单个商户优惠交易笔数上限 */
            BigDecimal quantityLimit = new BigDecimal(tmMcMchntFeeDiscountInfo.getQuantityLimit()).setScale(CommonConstant.DECIMAL_SCALE_ZERO, RoundingMode.HALF_UP);
            /* 单个商户优惠交易金额上限 */
            BigDecimal amountLimit = new BigDecimal(tmMcMchntFeeDiscountInfo.getAmountLimit()).setScale(CommonConstant.DECIMAL_SCALE_TWO, RoundingMode.HALF_UP);
            /* 单个商户手续费优惠额上限 */
            BigDecimal feeLimit = new BigDecimal(tmMcMchntFeeDiscountInfo.getFeeLimit()).setScale(CommonConstant.DECIMAL_SCALE_TWO, RoundingMode.HALF_UP);

            //计算商户已经消耗的预算值
            TMStatMfdMchnt tmStatMfdMchnt = calAlredyUsedFee(mchntNo, tmMcMchntFeeDiscountInfo, periodStartDate);

            //如果是新商户免手续费的，判断是否是无上限
            if (CommonConstant.MCHNT_NEW_FLAG.equals(feeDiscount.getNewMchntFlag())) {
                BigDecimal newMchntAmountLimit;

                if (null != feeDiscount.getMrctDisUpLmtVal() && !"".equals(feeDiscount.getMrctDisUpLmtVal())) {
                    rglog.info("营销活动<{}> 商户<{}> 达标统计表 商户优惠上限值 字段有值(或没有达标统计表数据的新商户直接使用新商户限额)，直接使用字段值<{}> 作为上限，无需通过计算规则重新计算!", mcNo, mchntNo, feeDiscount.getMrctDisUpLmtVal());
                    newMchntAmountLimit = new BigDecimal(feeDiscount.getMrctDisUpLmtVal());
                } else {
                    newMchntAmountLimit = new BigDecimal(feeDiscount.getFeeLimit());
                }

                rglog.info("法人机构<{}> 手续费优惠营销活动<{}> 商户<{}> 为新商户免手续费参与营销活动，新商户交易额度上限<{}>", globalInstId, mcNo, mchntNo, newMchntAmountLimit);
                if (CommonConstant.BIG_NUMBER.equals(newMchntAmountLimit.toString())) {
                    tmStatMfdMchnt.setRemark1("无上限");
                    //预算
                    tmStatMfdMchnt.setRemark2("无上限");
                } else {
                    String availAmt;
                    //新增商户免费额度类型
                    if (CommonConstant.ONE_COMMON_CONSTANT.equals(newmrctFreeLmtTyp)) {
                        availAmt = newMchntAmountLimit.subtract(new BigDecimal(tmStatMfdMchnt.getTotalAmtAcc())).setScale(CommonConstant.DECIMAL_SCALE_TWO, RoundingMode.HALF_UP).toString();
                    } else {
                        availAmt = newMchntAmountLimit.subtract(new BigDecimal(tmStatMfdMchnt.getTxnAmtAcc())).setScale(CommonConstant.DECIMAL_SCALE_TWO, RoundingMode.HALF_UP).toString();
                    }
                    tmStatMfdMchnt.setRemark1(availAmt + "元");
                    //预算
                    tmStatMfdMchnt.setRemark2(newMchntAmountLimit.toString() + "元");
                }
                //新增商户免费额度类型
                if (CommonConstant.ONE_COMMON_CONSTANT.equals(newmrctFreeLmtTyp)) {
                    tmStatMfdMchnt.setRemark4(CommonConstant.ONE_COMMON_CONSTANT);
                    //已使用额度
                    tmStatMfdMchnt.setRemark3(tmStatMfdMchnt.getTotalAmtAcc() + "元");
                } else {
                    tmStatMfdMchnt.setRemark4(CommonConstant.ZERO_COMMON_CONSTANT);
                    //已使用额度
                    tmStatMfdMchnt.setRemark3(tmStatMfdMchnt.getTxnAmtAcc() + "元");
                }
            } else {
                //查询商户手续费减免达标数据统计表数据,获取判断是否达标
                rglog.info("交易流水号<{}>,机构<{}>的商户<{}>查询商户手续费减免达标数据统计表", globalTraceNo, globalInstId, mchntNo);
                TMStatMfdCriteria tmStatMfdCriteria = selectTMStatMfdCriteriaByUsingMchntNoAndDateRange(globalInstId, mchntNo, globalTxnDate);
                //设置默认为剩余可用额度为交易金额
                tmStatMfdMchnt.setRemark4(CommonConstant.ZERO_COMMON_CONSTANT);

                if (null == tmStatMfdCriteria) {
                    rglog.info("机构<{}> 商户<{}> 获取手续费减免达标数据统计表失败!", globalInstId, mchntNo);
                    tmStatMfdMchnt.setRemark1(CommonConstant.ZERO_AMOUNT + "元");
                    //预算
                    tmStatMfdMchnt.setRemark2(CommonConstant.ZERO_AMOUNT + "元");
                    //已使用额度
                    tmStatMfdMchnt.setRemark3(CommonConstant.ZERO_AMOUNT + "元");
                    //添加到返回
                    statFeeMchntList.add(tmStatMfdMchnt);
                    return;
                }

                //判断达标标志
                String criteriaFlag = tmStatMfdCriteria.getCriteriaFlag();
                rglog.info("机构<{}> 营销活动<{}> 商户<{}> 达标统计表达标状态<{}> 0:未达标,1:已达标！", globalInstId, feeDiscount.getMcNo(), mchntNo, criteriaFlag);
                if (!CommonConstant.ONE_COMMON_CONSTANT.equals(criteriaFlag)) {
                    tmStatMfdMchnt.setRemark1(CommonConstant.ZERO_AMOUNT + "元");
                    //添加到返回
                    statFeeMchntList.add(tmStatMfdMchnt);
                    return;
                }

                if (BigDecimal.ZERO.compareTo(quantityLimit) < CommonConstant.ZERO) {
                    //剩余优惠笔数
                    String availAmt = quantityLimit.subtract(new BigDecimal(tmStatMfdMchnt.getTotalQtyAcc())).setScale(CommonConstant.DECIMAL_SCALE_ZERO, RoundingMode.HALF_UP).toString();
                    tmStatMfdMchnt.setRemark1(availAmt + "笔");
                    //预算
                    tmStatMfdMchnt.setRemark2(quantityLimit.toString() + "笔");
                    //已使用额度
                    tmStatMfdMchnt.setRemark3(tmStatMfdMchnt.getTotalQtyAcc() + "笔");
                    rglog.info("法人机构<{}> 手续费优惠营销活动<{}> 设置的为优惠笔数限额，剩余额度<{}>", globalInstId, mcNo, availAmt);
                    //设置 剩余可用额度为交易笔数
                    tmStatMfdMchnt.setRemark4(CommonConstant.TWO_COMMON_CONSTANT);
                } else if (BigDecimal.ZERO.compareTo(amountLimit) < CommonConstant.ZERO) {

                    if (null != tmStatMfdCriteria.getMrctDisUpLmtVal() && !"".equals(tmStatMfdCriteria.getMrctDisUpLmtVal())) {
                        rglog.info("营销活动<{}> 商户<{}> 达标统计表 商户优惠上限值 字段有值，直接使用字段值<{}> 作为上限，无需通过计算规则重新计算!", mcNo, mchntNo, feeDiscount.getMrctDisUpLmtVal());
                        amountLimit = new BigDecimal(tmStatMfdCriteria.getMrctDisUpLmtVal());
                    } else {
                    }

                    //剩余优惠交易金额
                    String availAmt = amountLimit.subtract(new BigDecimal(tmStatMfdMchnt.getTxnAmtAcc())).setScale(CommonConstant.DECIMAL_SCALE_TWO, RoundingMode.HALF_UP).toString();
                    tmStatMfdMchnt.setRemark1(availAmt + "元");
                    //预算
                    tmStatMfdMchnt.setRemark2(amountLimit.toString() + "元");
                    //已使用额度
                    tmStatMfdMchnt.setRemark3(tmStatMfdMchnt.getTxnAmtAcc() + "元");
                    rglog.info("法人机构<{}> 手续费优惠营销活动<{}> 设置的为优惠交易金额限额，剩余额度<{}>", globalInstId, mcNo, availAmt);
                    //设置 剩余可用额度为交易金额
                    tmStatMfdMchnt.setRemark4(CommonConstant.ZERO_COMMON_CONSTANT);

                } else if (BigDecimal.ZERO.compareTo(feeLimit) < CommonConstant.ZERO) {
                    //剩余手续费优惠额
                    String availAmt = feeLimit.subtract(new BigDecimal(tmStatMfdMchnt.getTotalAmtAcc())).setScale(CommonConstant.DECIMAL_SCALE_TWO, RoundingMode.HALF_UP).toString();
                    tmStatMfdMchnt.setRemark1(availAmt + "元");
                    //预算
                    tmStatMfdMchnt.setRemark2(feeLimit.toString() + "元");
                    //已使用额度
                    tmStatMfdMchnt.setRemark3(tmStatMfdMchnt.getTotalAmtAcc() + "元");
                    rglog.info("法人机构<{}> 手续费优惠营销活动<{}> 设置的为手续费优惠额限额，剩余额度<{}>", globalInstId, mcNo, availAmt);
                    //设置 剩余可用额度为手续费金额
                    tmStatMfdMchnt.setRemark4(CommonConstant.ONE_COMMON_CONSTANT);
                } else {
                }
            }

            //添加到返回
            statFeeMchntList.add(tmStatMfdMchnt);
        } else {
            rglog.info("法人机构<{}> 手续费优惠营销活动<{}> 未设置单个商户退出条件，剩余优惠额度使用配置的规则数据计算", globalInstId, mcNo, mchntNo);

            //计算商户已经消耗的预算值
            TMStatMfdMchnt tmStatMfdMchnt = calAlredyUsedFee(mchntNo, tmMcMchntFeeDiscountInfo, periodStartDate);
            //设置默认为剩余可用额度为交易金额
            tmStatMfdMchnt.setRemark4(CommonConstant.ZERO_COMMON_CONSTANT);

            //如果是新商户免手续费的，判断是否是无上限
            if (CommonConstant.MCHNT_NEW_FLAG.equals(feeDiscount.getNewMchntFlag())) {
                BigDecimal newMchntAmountLimit = new BigDecimal(feeDiscount.getFeeLimit());
                rglog.info("法人机构<{}> 手续费优惠营销活动<{}> 商户<{}> 为新商户免手续费参与营销活动，新商户交易额度上限<{}>", globalInstId, mcNo, mchntNo, newMchntAmountLimit);

                if (null != feeDiscount.getMrctDisUpLmtVal() && !"".equals(feeDiscount.getMrctDisUpLmtVal())) {
                    rglog.info("营销活动<{}> 商户<{}> 达标统计表 商户优惠上限值 字段有值(或没有达标统计表数据的新商户直接使用新商户限额)，直接使用字段值<{}> 作为上限，无需通过计算规则重新计算!", mcNo, mchntNo, feeDiscount.getMrctDisUpLmtVal());
                    newMchntAmountLimit = new BigDecimal(feeDiscount.getMrctDisUpLmtVal());
                } else {
                }
                if (CommonConstant.BIG_NUMBER.equals(newMchntAmountLimit.toString())) {
                    tmStatMfdMchnt.setRemark1("无上限");
                    //预算
                    tmStatMfdMchnt.setRemark2("无上限");
                } else {
                    String availAmt;
                    //新增商户免费额度类型
                    if (CommonConstant.ONE_COMMON_CONSTANT.equals(newmrctFreeLmtTyp)) {
                        availAmt = newMchntAmountLimit.subtract(new BigDecimal(tmStatMfdMchnt.getTotalAmtAcc())).setScale(CommonConstant.DECIMAL_SCALE_TWO, RoundingMode.HALF_UP).toString();
                    } else {
                        availAmt = newMchntAmountLimit.subtract(new BigDecimal(tmStatMfdMchnt.getTxnAmtAcc())).setScale(CommonConstant.DECIMAL_SCALE_TWO, RoundingMode.HALF_UP).toString();
                    }
                    tmStatMfdMchnt.setRemark1(availAmt + "元");
                    //预算
                    tmStatMfdMchnt.setRemark2(newMchntAmountLimit.toString() + "元");
                }
                //新增商户免费额度类型
                if (CommonConstant.ONE_COMMON_CONSTANT.equals(newmrctFreeLmtTyp)) {
                    tmStatMfdMchnt.setRemark4(CommonConstant.ONE_COMMON_CONSTANT);
                    //已使用额度
                    tmStatMfdMchnt.setRemark3(tmStatMfdMchnt.getTotalAmtAcc() + "元");
                } else {
                    tmStatMfdMchnt.setRemark4(CommonConstant.ZERO_COMMON_CONSTANT);
                    //已使用额度
                    tmStatMfdMchnt.setRemark3(tmStatMfdMchnt.getTxnAmtAcc() + "元");
                }
                //添加到返回
                statFeeMchntList.add(tmStatMfdMchnt);
                return;
            }

            //查询商户手续费减免达标数据统计表数据,获取统计表中的当前统计值，看是否达标，后续选出规则计算规则对应的优惠额度
            rglog.info("交易流水号<{}>,机构<{}>的商户<{}>查询商户手续费减免达标数据统计表", globalTraceNo, globalInstId, mchntNo);
            TMStatMfdCriteria tmStatMfdCriteria = selectTMStatMfdCriteriaByUsingMchntNoAndDateRange(globalInstId, mchntNo, globalTxnDate);

            if (null == tmStatMfdCriteria) {
                rglog.info("机构<{}> 商户<{}> 获取手续费减免达标数据统计表失败!", globalInstId, mchntNo);
                tmStatMfdMchnt.setRemark1(CommonConstant.ZERO_AMOUNT + "元");
                //预算
                tmStatMfdMchnt.setRemark2(CommonConstant.ZERO_AMOUNT + "元");
                //已使用额度
                tmStatMfdMchnt.setRemark3(CommonConstant.ZERO_AMOUNT + "元");
                //添加到返回
                statFeeMchntList.add(tmStatMfdMchnt);
                return;
            }

            //判断达标标志
            String criteriaFlag = tmStatMfdCriteria.getCriteriaFlag();
            //判断商户退出标志 0-正常优惠中 1-已退出优惠
            String exitDiscountStatus = tmStatMfdCriteria.getExitDiscountStatus();
            rglog.info("机构<{}> 营销活动<{}> 商户<{}> 达标统计表达标状态<{}> 0:未达标,1:已达标！ 商户优惠退出状态<{}> 0-正常优惠中 1-已退出优惠", globalInstId, feeDiscount.getMcNo(), mchntNo, criteriaFlag, exitDiscountStatus);
            if (!CommonConstant.ONE_COMMON_CONSTANT.equals(criteriaFlag)) {
                tmStatMfdMchnt.setRemark1(CommonConstant.ZERO_AMOUNT + "元");
                //预算
                tmStatMfdMchnt.setRemark2(CommonConstant.ZERO_AMOUNT + "元");
                //已使用额度
                tmStatMfdMchnt.setRemark3(CommonConstant.ZERO_AMOUNT + "元");
                //添加到返回
                statFeeMchntList.add(tmStatMfdMchnt);
                return;
            }

            BigDecimal totalDiscountLimit;

            //存量商户当前统计值
            String nowCriteriaValue = tmStatMfdCriteria.getCriteriaValue();

            //取营销活动规则信息
            List<TMMcMchntFeeDiscountRuleInfo> tmMcMchntFeeDiscountRuleInfoList = getMchntFeeDiscountMcRuleInfo(globalInstId, mcNo);
            if (null == tmMcMchntFeeDiscountRuleInfoList || tmMcMchntFeeDiscountRuleInfoList.isEmpty()) {
                /* 未取到营销活动规则信息,本营销活动不可以优惠! */
                rglog.info("获取机构<{}>的营销活动<{}>优惠规则信息匹配失败!", globalInstId, mcNo);
                throw new BizException(RespCodeEnum.GET_MC_RULE_INFO_ERROR.getRespCode(), RespCodeEnum.GET_MC_RULE_INFO_ERROR.getRespDesc());
            }

            /* 代码判断匹配到了哪条规则上 */
            TMMcMchntFeeDiscountRuleInfo tmMcMchntFeeDiscountRuleInfo;
            BigDecimal criteriaValue = new BigDecimal(nowCriteriaValue).setScale(CommonConstant.DECIMAL_SCALE_TWO, RoundingMode.HALF_UP);

            List<TMMcMchntFeeDiscountRuleInfo> tmMcMchntFeeDiscountRuleInfoList1 = new ArrayList<>();
            for (TMMcMchntFeeDiscountRuleInfo tmMcMchntFeeDiscountRuleInfo1 : tmMcMchntFeeDiscountRuleInfoList) {

                BigDecimal floor = new BigDecimal(tmMcMchntFeeDiscountRuleInfo1.getCriteriaFloor()).setScale(CommonConstant.DECIMAL_SCALE_TWO, RoundingMode.HALF_UP);
                BigDecimal celling = new BigDecimal(tmMcMchntFeeDiscountRuleInfo1.getCriteriaCelling()).setScale(CommonConstant.DECIMAL_SCALE_TWO, RoundingMode.HALF_UP);

                /* 按照左包右不包原则判断 */
                if (CommonConstant.ZERO <= criteriaValue.compareTo(floor) && CommonConstant.ZERO > criteriaValue.compareTo(celling)) {
                    tmMcMchntFeeDiscountRuleInfoList1.add(tmMcMchntFeeDiscountRuleInfo1);
                }
            }

            if (tmMcMchntFeeDiscountRuleInfoList1.isEmpty()) {
                /* 判断是否是因为当前统计指超过最高档规则上限,是的话按照最高档规则进行优惠 */
                tmMcMchntFeeDiscountRuleInfo = tmMcMchntFeeDiscountRuleInfoList.stream().max(Comparator.comparing(TMMcMchntFeeDiscountRuleInfo::getRuleIndex)).get();
                BigDecimal celling = new BigDecimal(tmMcMchntFeeDiscountRuleInfo.getCriteriaCelling()).setScale(CommonConstant.DECIMAL_SCALE_TWO, RoundingMode.HALF_UP);
                if (CommonConstant.ZERO >= celling.compareTo(criteriaValue)) {
                    rglog.info("当前商户<{}>的达标统计值<{}>超过最高一档规则上限<{}>,按照该档规则计算!", mchntNo, criteriaValue.toString(), celling.toString());
                    tmMcMchntFeeDiscountRuleInfoList1.add(tmMcMchntFeeDiscountRuleInfo);
                } else {
                    tmStatMfdMchnt.setRemark1(CommonConstant.ZERO_AMOUNT + "元");
                    //预算
                    tmStatMfdMchnt.setRemark2(CommonConstant.ZERO_AMOUNT + "元");
                    //已使用额度
                    tmStatMfdMchnt.setRemark3(CommonConstant.ZERO_AMOUNT + "元");
                    rglog.info("当前商户<{}>的达标统计值<{}>未获取到符合条件的规则，剩余额度直接置为0!", mchntNo, criteriaValue.toString());
                    //添加到返回
                    statFeeMchntList.add(tmStatMfdMchnt);
                    return;
                }
            }

            if (null != tmStatMfdCriteria.getMrctDisUpLmtVal() && !"".equals(tmStatMfdCriteria.getMrctDisUpLmtVal())) {
                rglog.info("营销活动<{}> 商户<{}> 达标统计表 商户优惠上限值 字段有值，直接使用字段值<{}> 作为上限，无需通过计算规则重新计算!", mcNo, mchntNo, feeDiscount.getMrctDisUpLmtVal());
                totalDiscountLimit = new BigDecimal(tmStatMfdCriteria.getMrctDisUpLmtVal());
            } else if (FeeCalTypeEnum.TYPE_1.getRuleType().equals(tmMcMchntFeeDiscountRuleInfoList1.get(CommonConstant.ZERO).getCalRuleNo()) ||
                    FeeCalTypeEnum.TYPE_13.getRuleType().equals(tmMcMchntFeeDiscountRuleInfoList1.get(CommonConstant.ZERO).getCalRuleNo())) {
                rglog.info("营销活动<{}> 商户<{}> 达标统计表 商户优惠上限值 字段无值，当前规则为<{}>，指定商户手续费上限或交易金额上限，直接取规则表中的值!", mcNo, mchntNo, tmMcMchntFeeDiscountRuleInfoList1.get(CommonConstant.ZERO).getCalRuleNo());
                /* 无需取优惠限额的计算规则,直接使用规则中的限额 */
                totalDiscountLimit = new BigDecimal(tmMcMchntFeeDiscountRuleInfoList1.get(CommonConstant.ZERO).getDiscountLimit());

            } else {
                rglog.info("营销活动<{}> 商户<{}> 达标统计表 商户优惠上限值 字段无值，当前规则为<{}>，需计算规则上限!", mcNo, mchntNo, tmMcMchntFeeDiscountRuleInfoList1.get(CommonConstant.ZERO).getCalRuleNo());
                //计算规则的优惠限制
                totalDiscountLimit = calculateMchntFeeDiscountLimit(mchntNo, tmMcMchntFeeDiscountRuleInfoList1.get(CommonConstant.ZERO), nowCriteriaValue);
            }

            String ruleNo = tmMcMchntFeeDiscountRuleInfoList1.get(CommonConstant.ZERO).getCalRuleNo();

            rglog.info("机构<{}> 营销活动<{}> 规则总营销额度为<{}>!", globalInstId, mcNo, totalDiscountLimit.toString());
            //如果规则是无上限的，剩余额度为无限大
            if (CommonConstant.BIG_NUMBER.equals(totalDiscountLimit.toString())) {
                tmStatMfdMchnt.setRemark1("无上限");
                //预算
                tmStatMfdMchnt.setRemark2("无上限");
            } else {
                //计算剩余的额度
                String availAmt;
                if (FeeCalTypeEnum.TYPE_13.getRuleType().equals(ruleNo)) {
                    availAmt = totalDiscountLimit.subtract(new BigDecimal(tmStatMfdMchnt.getTotalAmtAcc())).toString();
                    //设置 剩余可用额度为手续费金额
                    tmStatMfdMchnt.setRemark4(CommonConstant.ONE_COMMON_CONSTANT);
                } else {
                    availAmt = totalDiscountLimit.subtract(new BigDecimal(tmStatMfdMchnt.getTxnAmtAcc())).toString();
                    //设置 剩余可用额度为交易金额
                    tmStatMfdMchnt.setRemark4(CommonConstant.ZERO_COMMON_CONSTANT);
                }
                tmStatMfdMchnt.setRemark1(availAmt + "元");
                //预算
                tmStatMfdMchnt.setRemark2(totalDiscountLimit.toString() + "元");
            }
            //判断已使用额度如何取值
            if (FeeCalTypeEnum.TYPE_13.getRuleType().equals(ruleNo)) {
                //已使用额度
                tmStatMfdMchnt.setRemark3(tmStatMfdMchnt.getTotalAmtAcc() + "元");
            } else {
                //已使用额度
                tmStatMfdMchnt.setRemark3(tmStatMfdMchnt.getTxnAmtAcc() + "元");
            }
            //添加到返回
            statFeeMchntList.add(tmStatMfdMchnt);
        }
    }

    /**
     * @param queryMchnFeeDiscountDetailRequest
     * @return void
     * @throws Exception 异常信息
     * @author liujinan
     * @date 2020/4/7
     * @Description: 查询商户手续费优惠单日统计信息
     */
    private void getMchntFeeDiscountDayInfo(QueryMchnFeeDiscountDetailRequest queryMchnFeeDiscountDetailRequest, String mcNo, String mchntNo, List<TMStatMfdMchntDay> statFeeMchntDayDayList) {
        //获取当前日期
        String nowDate = DateUtil.getCurrentDate();
        String queryClause = queryMchnFeeDiscountDetailRequest.getHeader().getInstId() + mcNo + nowDate;

        try {
            StatisticsStatementInfoMapper statisticsStatementInfoMapper = new StatisticsStatementInfoMapperImpl();
            List<TMStatMfdMchntDay> objectList = statisticsStatementInfoMapper.selectStatFeeMchntDayListInfo(queryMchnFeeDiscountDetailRequest.getHeader().getInstId(),
                    mcNo, nowDate, mchntNo);
            if (null != objectList) {
                statFeeMchntDayDayList.addAll(objectList);
            }
        } catch (Exception e) {
            rglog.error("根据查询条件<{}>获取商户手续费减免活动商户单日统计信息失败!", queryClause);
            throw new BizException(RespCodeEnum.GET_MONEY_OFF_MC_LIST_ERROR.getRespCode(), RespCodeEnum.GET_MONEY_OFF_MC_LIST_ERROR.getRespDesc());
        }
    }

    /**
     * @return cc.rengu.igas.momp.facade.bean.MchntFeeDiscountMcStatInfoBean
     * @throws Exception 异常信息
     * @author liujinan
     * @date 2020/4/7
     * @Description: 手续费减免活动商户统计表转换为商户手续费优惠营销活动数据统计信息对象列表
     */
    private List<MchntFeeDiscountMcStatInfoBean> convertStatFeeMchntInfoBean(List<TMStatMfdMchnt> tmStatMfdMchntList, String feeLimit) {

        List<MchntFeeDiscountMcStatInfoBean> mchntFeeDiscountMcStatInfoBeanList = new ArrayList<>();

        try {
            for (TMStatMfdMchnt statFeeMchnt : tmStatMfdMchntList) {
                MchntFeeDiscountMcStatInfoBean mchntFeeDiscountMcStatInfoBean = new MchntFeeDiscountMcStatInfoBean();
                //起始日期
                mchntFeeDiscountMcStatInfoBean.setStartDate(statFeeMchnt.getStatStartDate());
                //结束日期
                mchntFeeDiscountMcStatInfoBean.setEndDate(statFeeMchnt.getStatEndDate());
                //营销活动编号
                mchntFeeDiscountMcStatInfoBean.setMcNo(statFeeMchnt.getMcNo());
                //商户号
                mchntFeeDiscountMcStatInfoBean.setMchntNo(statFeeMchnt.getMchntNo());
                //累计消耗笔数
                mchntFeeDiscountMcStatInfoBean.setTotalQtyAcc(statFeeMchnt.getTotalQtyAcc());
                //累计消耗金额
                mchntFeeDiscountMcStatInfoBean.setTotalAmtAcc(statFeeMchnt.getTotalAmtAcc());

                String avgTotalAmt = CommonConstant.ZERO_COMMON_CONSTANT;
                if (!CommonConstant.ZERO_COMMON_CONSTANT.equals(statFeeMchnt.getTotalQtyAcc())) {
                    avgTotalAmt = new BigDecimal(statFeeMchnt.getTotalAmtAcc()).divide(new BigDecimal(statFeeMchnt.getTotalQtyAcc()), CommonConstant.DECIMAL_SCALE_TWO, RoundingMode.HALF_UP).toString();
                }
                //笔均消耗金额
                mchntFeeDiscountMcStatInfoBean.setAvgTotalAmt(avgTotalAmt);
                //日均交易笔数
                mchntFeeDiscountMcStatInfoBean.setAvgDayQty(statFeeMchnt.getDayAvgAmt());
                //日均交易金额
                mchntFeeDiscountMcStatInfoBean.setAvgDayAmt(statFeeMchnt.getDayAvgAmt());
                //剩余可用优惠金额
                mchntFeeDiscountMcStatInfoBean.setAvailAmt(statFeeMchnt.getRemark1());
                //预算
                mchntFeeDiscountMcStatInfoBean.setBudget(statFeeMchnt.getRemark2());
                //已使用额度
                mchntFeeDiscountMcStatInfoBean.setUsedLmt(statFeeMchnt.getRemark3());
                //剩余可用优惠金额类型
                mchntFeeDiscountMcStatInfoBean.setAvailAmtType(statFeeMchnt.getRemark4());

                mchntFeeDiscountMcStatInfoBeanList.add(mchntFeeDiscountMcStatInfoBean);
            }
        } catch (Exception e) {
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            e.printStackTrace(new PrintWriter(byteArrayOutputStream, true));
            rglog.error("转换商户手续费优惠统计信息异常,异常信息:<{}>", byteArrayOutputStream.toString());
            throw new BizException(RespCodeEnum.SYSTEM_ERROR.getRespCode(), RespCodeEnum.SYSTEM_ERROR.getRespDesc());
        }
        return mchntFeeDiscountMcStatInfoBeanList;
    }

    /**
     * @return cc.rengu.igas.momp.facade.bean.MchntToClientMcTxnStatInfoBean
     * @throws Exception 异常信息
     * @author liujinan
     * @date 2020/4/7
     * @Description: 手续费减免活动商户统计表转换为商户手续费优惠营销活动数据统计信息对象列表
     */
    private MchntFeeDiscountMcTxnStatInfoBean convertStatFeeMchntDayInfoBean(TMStatMfdMchntDay statFeeMchntDay) {
        MchntFeeDiscountMcTxnStatInfoBean mchntFeeDiscountMcTxnStatInfoBean = new MchntFeeDiscountMcTxnStatInfoBean();
        try {
            //统计表中没有的字段,赋值为0
            //交易日期
            mchntFeeDiscountMcTxnStatInfoBean.setTxnDate(statFeeMchntDay.getTxnDate());
            //活动期间交易笔数
            if (!StringUtil.isNullorEmpty(statFeeMchntDay.getTotalQtyAcc())) {
                mchntFeeDiscountMcTxnStatInfoBean.setMcQty(statFeeMchntDay.getTotalQtyAcc());
            } else {
                mchntFeeDiscountMcTxnStatInfoBean.setMcQty(CommonConstant.ZERO_COMMON_CONSTANT);
            }
            //原日均交易笔数
            if (!StringUtil.isNullorEmpty(initStatData) && !CommonConstant.ZERO_COMMON_CONSTANT.equals(initStatData)) {
                mchntFeeDiscountMcTxnStatInfoBean.setOriginalQty(JSON.parseObject(initStatData).getString("dayAvgCount"));
            } else {
                mchntFeeDiscountMcTxnStatInfoBean.setOriginalQty(CommonConstant.ZERO_COMMON_CONSTANT);
            }
            //活动期间交易金额
            if (!StringUtil.isNullorEmpty(statFeeMchntDay.getTotalAmtAcc())) {
                mchntFeeDiscountMcTxnStatInfoBean.setMcAmt(statFeeMchntDay.getTotalAmtAcc());
            } else {
                mchntFeeDiscountMcTxnStatInfoBean.setMcAmt(CommonConstant.ZERO_AMOUNT);
            }
            //原日均交易金额
            if (!StringUtil.isNullorEmpty(initStatData) && !CommonConstant.ZERO_COMMON_CONSTANT.equals(initStatData)) {
                mchntFeeDiscountMcTxnStatInfoBean.setOriginalAmt(JSON.parseObject(initStatData).getString("dayAvgAmount"));
            } else {
                mchntFeeDiscountMcTxnStatInfoBean.setOriginalAmt(CommonConstant.ZERO_AMOUNT);
            }
        } catch (Exception e) {
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            e.printStackTrace(new PrintWriter(byteArrayOutputStream, true));
            rglog.error("转换商户手续费优惠单日统计信息异常,异常信息:<{}>", byteArrayOutputStream.toString());
            throw new BizException(RespCodeEnum.SYSTEM_ERROR.getRespCode(), RespCodeEnum.SYSTEM_ERROR.getRespDesc());
        }
        return mchntFeeDiscountMcTxnStatInfoBean;
    }

    /**
     * 检查商户是否可作为手续费优惠活动的新增商户
     * 返回true-成功
     * 返回false-失败，不可作为新商户享受免手续费优惠
     *
     * @param tmMcMchntFeeDiscountInfo 商户手续费减免类营销活动信息表
     * @param mchntExpandDate          商户入驻日期
     * @return boolean 返回码
     * @throws Exception 异常信息
     * @author liujinan
     * @date 2020/9/15 15:38
     */
    private boolean checkNewMchntAvailability(String mchntNo, TMMcMchntFeeDiscountInfo tmMcMchntFeeDiscountInfo, String mchntExpandDate, Boolean notDistinguishMiddleOfMonth) throws Exception {

        String mcNo = tmMcMchntFeeDiscountInfo.getMcNo();

        int monthPeriod = Integer.parseInt(tmMcMchntFeeDiscountInfo.getNewMchntPeriod());

        String periodEndDate;
        //不区分15号之前之后时
        if (notDistinguishMiddleOfMonth) {
            periodEndDate = MompDateUtil.getFutureMonFirstDay(mchntExpandDate, monthPeriod);
        } else {
            periodEndDate = MompDateUtil.getFutureMonAddOneFirstDay(mchntExpandDate, monthPeriod);
        }

        String mcEndDate = tmMcMchntFeeDiscountInfo.getMcEndDate();
        String postponeFlag = tmMcMchntFeeDiscountInfo.getPostponeFlag();

        //如果免手续费到期时间在活动结束时间之前
        if (MompDateUtil.checkDateRange(periodEndDate, mcEndDate)) {
            tmMcMchntFeeDiscountInfo.setRemark1(periodEndDate);
        } else {
            //判断是否顺延，如果顺延，免费周期为顺延后的到期时间，保存到remark1中,后续使用此字段判断免费周期最长的
            if (CommonConstant.NEW_MCHNT_DISCOUNT_PROLONG.equals(postponeFlag)) {
                tmMcMchntFeeDiscountInfo.setRemark1(periodEndDate);
            } else {
                tmMcMchntFeeDiscountInfo.setRemark1(mcEndDate);
            }
        }

        if (MompDateUtil.checkDateRange(globalTxnDate, mcEndDate) && MompDateUtil.checkDateRange(globalTxnDate, periodEndDate)) {
            /* 当前交易日期同时在活动结束日期和最后的新商户统计周期内,可以优惠 */
            rglog.info("法人机构<{}>的商户手续费优惠活动<{}> 商户<{}>在新商户免手续费周期内!", globalInstId, mcNo, mchntNo);
            return true;

        } else if (MompDateUtil.checkDateRange(globalTxnDate, periodEndDate)) {

            /* 当前交易日期在活动结束日期外,但在新商户统计周期内,需进一步判断 */
            if (CommonConstant.NEW_MCHNT_DISCOUNT_END.equals(postponeFlag)) {
                /* 活动结束后周期不自动顺延,即活动结束后就没有新商户免手续费的优惠 */
                rglog.error("法人机构<{}>的商户手续费优惠活动<{}>不支持新增商户周期顺延!商户<{}>不在新商户免手续费周期内!", globalInstId, mcNo, mchntNo);
                return false;

            } else if (CommonConstant.NEW_MCHNT_DISCOUNT_PROLONG.equals(postponeFlag)) {
                /* 商户手续费优惠营销活动新入驻商户活动结束后周期自动顺延 */
                rglog.info("法人机构<{}>的商户手续费优惠活动<{}>支持新增商户周期顺延!商户<{}>在新商户免手续费周期内!", globalInstId, mcNo, mchntNo);
                return true;

            } else {
                rglog.error("法人机构<{}>的商户手续费优惠活动<{}>的新增商户周期顺延标志数据异常 !", globalInstId, mcNo, mchntNo);
                return false;
            }
        } else {
            rglog.error("商户<{}>在当前日期<{}>已不满足参加法人机构<{}>的商户手续费优惠活动<{}>并免手续费的条件!", mchntNo, globalTxnDate, globalInstId, mcNo);
            return false;
        }
    }

    /**
     * 使用营销活动商户信息对象获取商户手续费优惠类营销活动基本信息
     *
     * @param instId
     * @param mcNo
     * @return cc.rengu.igas.momp.common.entity.TMMcMchntFeeDiscountInfo
     * @throws Exception 异常信息
     * @author liujinan
     * @date 2020/9/15
     */
    private TMMcMchntFeeDiscountInfo getMchntFeeDiscountMcInfo(String instId, String mcNo) throws Exception {
        McDetailInfoMapper mcDetailInfoMapper = new McDetailInfoMapperImpl();
        return mcDetailInfoMapper.selectMchntFeeDiscountMcDetailInfo(instId, mcNo);
    }

    /**
     * 使用主键查询手续费减免活动周期统计表单条数据
     *
     * @param instId
     * @param mcNo
     * @param ruleIndex
     * @param periodStartDate
     * @param periodEndDate
     * @return cc.rengu.igas.momp.common.entity.TMStatMfdPeriod
     * @throws Exception
     * @author liujinan
     * @date 2020/9/15
     */
    private TMStatMfdPeriod selectMchntFeeDiscountPeriodStatisticsByPK(String instId, String mcNo, String ruleIndex, String periodStartDate, String periodEndDate) throws Exception {

        TMStatMfdPeriodMapper tmStatMfdPeriodMapper = new TMStatMfdPeriodMapperImpl();
        return tmStatMfdPeriodMapper.selectMchntFeeDiscountPeriodStatisticsByPK(instId, mcNo, ruleIndex, periodStartDate, periodEndDate);
    }

    /**
     * 使用主键取手续费减免活动商户统计表单条数据
     *
     * @param instId
     * @param mcNo
     * @param ruleIndex
     * @param mchntNo
     * @return cc.rengu.igas.momp.common.entity.TMStatMfdMchnt
     * @throws Exception
     * @author liujinan
     * @date 2020/9/15
     */
    private TMStatMfdMchnt selectNowPeriodDateTMStatMfdMchnt(String instId, String mcNo, String ruleIndex, String mchntNo, String txnDate) throws Exception {

        TMStatMfdMchntMapper tmStatMfdMchntMapper = new TMStatMfdMchntMapperImpl();
        return tmStatMfdMchntMapper.selectNowPeriodDateTMStatMfdMchnt(instId, mcNo, ruleIndex, mchntNo, txnDate);
    }

    /**
     * 查询商户已经使用的优惠额度值
     *
     * @return cc.rengu.igas.momp.common.entity.TMStatMfdMchnt
     * @throws Exception
     * @author liujinan
     * @date 2020/9/16
     */
    private TMStatMfdMchnt calAlredyUsedFee(String mchntNo, TMMcMchntFeeDiscountInfo tmMcMchntFeeDiscountInfo, String periodStartDate) throws Exception {

        String mcNo = tmMcMchntFeeDiscountInfo.getMcNo();

        int batchStatus = CommonConstant.FLAG_NOT_SET;
        String mcStartDate = tmMcMchntFeeDiscountInfo.getMcStartDate();
        String lastDate = DateUtil.getBaseDateOffsetDay(globalTxnDate, CommonConstant.MINUS_ONE);
        String lastSecondDate = DateUtil.getBaseDateOffsetDay(lastDate, CommonConstant.MINUS_ONE);
        String mcType = tmMcMchntFeeDiscountInfo.getMcType();

        //获取统计数据不判断跑批异常，然后抛出异常，抛出会导致商户服务页面异常

        //查询商户手续费优惠营销活动商户统计表数据
        TMStatMfdMchnt tmStatMfdMchnt = selectNowPeriodDateTMStatMfdMchnt(globalInstId, mcNo, CommonConstant.ZERO_COMMON_CONSTANT, mchntNo, globalTxnDate);
        if (null == tmStatMfdMchnt) {
            rglog.info("机构<{}> 营销活动<{}> 规则<{}> 营销活动商户统计表无数据!", globalInstId, mcNo, CommonConstant.ZERO_COMMON_CONSTANT);

            //取到0条数据,说明该营销活动还未产生统计值,按所有统计值都是0进行处理
            tmStatMfdMchnt = new TMStatMfdMchnt();
            tmStatMfdMchnt.setTotalQtyAcc(CommonConstant.ZERO_COMMON_CONSTANT);
            tmStatMfdMchnt.setTotalAmtAcc(CommonConstant.ZERO_COMMON_CONSTANT);
            tmStatMfdMchnt.setTxnAmtAcc(CommonConstant.ZERO_COMMON_CONSTANT);
            tmStatMfdMchnt.setTxnQtyAcc(CommonConstant.ZERO_COMMON_CONSTANT);
            tmStatMfdMchnt.setMchntNo(mchntNo);
            tmStatMfdMchnt.setMcNo(mcNo);

            rglog.info("机构<{}> 手续优惠营销活动<{}> 营销活动商户统计表无数据!", globalInstId, mcNo);

        }
        String batchDate;
        //查询统计信息备份表批次信息 查询营销活动信息表的批量处理情况即可
        String statPrimaryKey = "FeeMchnt" + globalInstId + "_" + mcNo;
        TMStatBak tmStatBak = selectTMStatBakByStatPrimaryKey(globalInstId, mcType, statPrimaryKey);
        //批次表为空，从来没执行过批量任务
        if (null == tmStatBak) {
            //从来没执行过批量任务，则从活动开始的第一天开始取数据
            batchDate = periodStartDate;
        } else {
            batchDate = DateUtil.getBaseDateOffsetDay(tmStatBak.getBatchDate(), 1);
        }
        //批量处理的日期小于昨天的日期，则需要取之前的数据
        while (DateUtil.compareDate(batchDate, lastDate) <= 0) {
            //获取的数据累加到活动统计中
            /* 查询商户手续费优惠营销活动商户单日统计表数据 具体规则编号的数据*/
            TMStatMfdMchntDay newtmStatMfdMchntDay = selectMchntFeeDiscountMchntDayStatisticsByPK(globalInstId, mcNo, CommonConstant.ZERO_COMMON_CONSTANT, mchntNo, batchDate);
            if (null == newtmStatMfdMchntDay) {
                rglog.error("机构<{}> 商户<{}> 商户手续费优惠营销活动<{}> 规则<{}> 商户手续费优惠营销活动商户单日统计表数据查询失败!", globalInstId, mchntNo, mcNo, CommonConstant.ZERO_COMMON_CONSTANT);
                newtmStatMfdMchntDay = new TMStatMfdMchntDay();
                newtmStatMfdMchntDay.setTotalQtyAcc(CommonConstant.ZERO_COMMON_CONSTANT);
                newtmStatMfdMchntDay.setTotalAmtAcc(CommonConstant.ZERO_COMMON_CONSTANT);
                newtmStatMfdMchntDay.setTxnQtyAcc(CommonConstant.ZERO_COMMON_CONSTANT);
                newtmStatMfdMchntDay.setTxnAmtAcc(CommonConstant.ZERO_COMMON_CONSTANT);
            }
            //将单日统计表的数据累加到周期数据上
            if (DateUtil.compareDate(batchDate, periodStartDate) < 0) {
                rglog.error("获取日期<{}>的单日统计不属于在本统计周期中，不需要累加到商户统计表!", batchDate);
            } else {
                rglog.error("获取日期<{}>的单日统计属于在本统计周期中，需要累加到商户统计表!", batchDate);
                copyMchntStatMfdData(tmStatMfdMchnt, newtmStatMfdMchntDay);
            }
            //将批次日期加一天继续判断
            batchDate = DateUtil.getBaseDateOffsetDay(batchDate, 1);
        }
        //查询手续费减免活动商户单日统计表数据
        TMStatMfdMchntDayMapper tmStatMfdMchntDayMapper = new TMStatMfdMchntDayMapperImpl();
        TMStatMfdMchntDay tmStatMfdMchntDay = tmStatMfdMchntDayMapper.selectMchntFeeDiscountMchntDayStatisticsByPK(globalInstId, mcNo, CommonConstant.ZERO_COMMON_CONSTANT,
                mchntNo, globalTxnDate);
        if (null == tmStatMfdMchntDay) {
            rglog.error("机构<{}>的手续优惠营销活动<{}>的规则<{}>对客户营销活动单日统计表数据查询失败!", globalInstId, mcNo, CommonConstant.ZERO_COMMON_CONSTANT);
            //取到0条数据,说明该营销活动还未产生统计值,按所有统计值都是0进行处理
            tmStatMfdMchntDay = new TMStatMfdMchntDay();
            tmStatMfdMchntDay.setTotalAmtAcc(CommonConstant.ZERO_COMMON_CONSTANT);
            tmStatMfdMchntDay.setTotalQtyAcc(CommonConstant.ZERO_COMMON_CONSTANT);
            tmStatMfdMchntDay.setTxnAmtAcc(CommonConstant.ZERO_COMMON_CONSTANT);
        }


        tmStatMfdMchnt.setTotalQtyAcc(new BigDecimal(tmStatMfdMchnt.getTotalQtyAcc()).add(new BigDecimal(tmStatMfdMchntDay.getTotalQtyAcc())).toString());
        tmStatMfdMchnt.setTotalAmtAcc(new BigDecimal(tmStatMfdMchnt.getTotalAmtAcc()).add(new BigDecimal(tmStatMfdMchntDay.getTotalAmtAcc())).toString());
        tmStatMfdMchnt.setTxnAmtAcc(new BigDecimal(tmStatMfdMchnt.getTxnAmtAcc()).add(new BigDecimal(tmStatMfdMchntDay.getTxnAmtAcc())).toString());

        return tmStatMfdMchnt;
    }

    /**
     * 取营销活动规则
     *
     * @param instId 法人机构号
     * @param mcNo   营销活动编号
     * @throws Exception 异常信息
     * @author liujinan
     * @since 2020/9/16 18:01
     */
    private List<TMMcMchntFeeDiscountRuleInfo> getMchntFeeDiscountMcRuleInfo(String instId, String mcNo) throws Exception {

        McRuleInfoMapper mcRuleInfoMapper = new McRuleInfoMapperImpl();
        return mcRuleInfoMapper.selectMchntFeeDiscountRuleInfoList(instId, mcNo);
    }

    /**
     * 根据计算规则计算规则优惠限额
     *
     * @throws Exception 异常信息
     * @author liujinan
     * @since 2020/9/16 02:41
     */
    private BigDecimal calculateMchntFeeDiscountLimit(String mchntNo, TMMcMchntFeeDiscountRuleInfo tmMcMchntFeeDiscountRuleInfo, String nowCriteriaValue) throws Exception {

        String month = DateUtil.getFutureMonDay(CommonConstant.MINUS_ONE).substring(0, 6);
        rglog.debug("INST_ID=<{}>, MCHNT_NO=<{}>, MONTH=<{}>", globalInstId, mchntNo, month);

        //商户上月日均余额直接取达标统计表中的当前统计值
        String mchntDeposit = nowCriteriaValue;

        BigDecimal TWO = new BigDecimal("2");
        BigDecimal HUNDARD_1 = new BigDecimal("125");
        BigDecimal HUNDARD_5 = new BigDecimal("500");
        BigDecimal THOUSAND_30 = new BigDecimal("30000");
        BigDecimal THOUSAND_50 = new BigDecimal("50000");
        BigDecimal THOUSAND_100 = new BigDecimal("100000");

        BigDecimal deposit = new BigDecimal(mchntDeposit).setScale(CommonConstant.DECIMAL_SCALE_TWO, RoundingMode.HALF_UP);
        BigDecimal tenThousand = new BigDecimal("10000").setScale(CommonConstant.DECIMAL_SCALE_TWO, RoundingMode.HALF_UP);
        BigDecimal discountLimit;

        String calRuleNo = tmMcMchntFeeDiscountRuleInfo.getCalRuleNo();
        if (null != calRuleNo) {
            switch (FeeCalTypeEnum.getByValue(calRuleNo)) {
                case TYPE_0:
                    /* 无上限 */
                    discountLimit = new BigDecimal(CommonConstant.BIG_NUMBER);
                    break;
                case TYPE_1:
                    /* 指定具体数值 */
                    discountLimit = new BigDecimal(tmMcMchntFeeDiscountRuleInfo.getDiscountLimit());
                    break;
                case TYPE_2:
                    /* 上月日均存款万位取整+3万 */
                    discountLimit = deposit.divideToIntegralValue(tenThousand).add(THOUSAND_30);
                    break;
                case TYPE_3:
                    /* 上月日均存款*2+3万 */
                    discountLimit = deposit.multiply(TWO).add(THOUSAND_30);
                    break;
                case TYPE_4:
                    /* 上月日均存款万位取整+5万 */
                    discountLimit = deposit.divideToIntegralValue(tenThousand).add(THOUSAND_50);
                    break;
                case TYPE_5:
                    /* 上月日均存款*2+5万 */
                    discountLimit = deposit.multiply(TWO).add(THOUSAND_50);
                    break;
                case TYPE_6:
                    /* 上月日均存款每10万优惠125元 */
                    discountLimit = deposit.divide(THOUSAND_100).multiply(HUNDARD_1);
                    break;
                case TYPE_7:
                    /* 上月日均存款每10万优惠500元 */
                    discountLimit = deposit.divide(THOUSAND_100).multiply(HUNDARD_5);
                    break;
                case TYPE_8:
                    /* 上月日均存款 */
                    discountLimit = deposit;
                    break;
                case TYPE_9:
                    /* 上月日均存款每万元取整*2+3万 */
                    rglog.info("手续费计算规则类型 <{}> 上月日均存款每万元*2+3万", calRuleNo);
                    discountLimit = deposit.divideToIntegralValue(tenThousand).multiply(TWO).multiply(tenThousand).add(THOUSAND_30);
                    break;
                case TYPE_10:
                    /* 上月日均存款每万元*2+5万 */
                    rglog.info("手续费计算规则类型 <{}> 上月日均存款每万元*2+5万", calRuleNo);
                    discountLimit = deposit.divideToIntegralValue(tenThousand).multiply(TWO).multiply(tenThousand).add(THOUSAND_50);
                    break;
                case TYPE_11:
                    /* 上月日均存款每十万元*2+3万 */
                    rglog.info("手续费计算规则类型 <{}> 上月日均存款每十万元*2+3万", calRuleNo);
                    discountLimit = deposit.divideToIntegralValue(THOUSAND_100).multiply(THOUSAND_100).multiply(TWO).add(THOUSAND_30);
                    break;
                case TYPE_12:
                    /* 上月日均存款每十万元*2+5万 */
                    rglog.info("手续费计算规则类型 <{}> 上月日均存款每十万元*2+5万", calRuleNo);
                    discountLimit = deposit.divideToIntegralValue(THOUSAND_100).multiply(THOUSAND_100).multiply(TWO).add(THOUSAND_50);
                    break;
                default:
                    discountLimit = new BigDecimal(CommonConstant.ZERO_AMOUNT);
                    rglog.error("营销活动<{}> 规则类型<{}> 手续费优惠限额计算规则类型错误！", tmMcMchntFeeDiscountRuleInfo.getMcNo(), FeeCalTypeEnum.getByValue(calRuleNo));
                    break;
            }
            rglog.info("营销活动<{}> 规则<{}> 规则最高限额<{}>", tmMcMchntFeeDiscountRuleInfo.getMcNo(), tmMcMchntFeeDiscountRuleInfo.getRuleIndex(), discountLimit);
        } else {
            discountLimit = new BigDecimal(CommonConstant.ZERO_AMOUNT);
            rglog.error("营销活动<{}> 手续费优惠计算规则编号为空！", tmMcMchntFeeDiscountRuleInfo.getMcNo());
        }
        return discountLimit;
    }

    /**
     * 使用商户编号和当前交易日期获取商户当前统计周期内已参加的商户手续费优惠营销活动统计数据
     *
     * @param instId
     * @param mchntNo
     * @param transDate
     * @return cc.rengu.igas.momp.common.entity.TMStatMfdCriteria
     * @throws Exception 异常信息
     * @author liujinan
     * @date 2020/6/5
     */
    private TMStatMfdCriteria selectTMStatMfdCriteriaByUsingMchntNoAndDateRange(String instId, String mchntNo, String transDate) throws Exception {
        TMStatMfdCriteriaMapper tmStatMfdCriteriaMapper = new TMStatMfdCriteriaMapperImpl();
        return tmStatMfdCriteriaMapper.selectTMStatMfdCriteriaByMchntNoAndDateRange(instId, mchntNo, transDate);
    }

    /**
     * 判断是否存在新商户手续费优惠活动，如果存在则返回
     *
     * @return cc.rengu.igas.momp.common.entity.TMStatMfdCriteria
     * @throws Exception 异常信息
     * @author liujinan
     * @date 2021/3/1
     */
    private StatisticsStatementQueryRespInfo judgeIsExitNewMchntMc(QueryMchnFeeDiscountDetailRequest queryMchnFeeDiscountDetailRequest, TBMchntBaseInfo mchntBaseInfo) throws Exception {
        //如果没有查询到活动，需要判断商户入驻期间有没有开展的新商户的营销活动，商户参加的
        rglog.info("机构<{}> 商户<{}> 商圈<{}> 未查询到参加的存量商户的营销活动，继续判断存在入驻期间有对于新商户开展的活动", globalInstId, mchntBaseInfo.getMchntNo(), mchntBaseInfo.getMchntArea());
        String orgId = queryMchnFeeDiscountDetailRequest.getQueryOrgId();
        //机构编码
        String instId = queryMchnFeeDiscountDetailRequest.getHeader().getInstId();
        //商户号
        String mchntNo = mchntBaseInfo.getMchntNo();

        /* 判断商户是否重复入网商户 */
        boolean repeatFlag = checkMchntRepeatFlag(mchntNo, mchntBaseInfo.getMchntExpandTime());
        if (repeatFlag) {
            rglog.info("法人机构<{}>的商户<{}>所在机构<{}>为重复入网商户,该商户无法享受任何商户手续费优惠!", globalInstId, mchntNo, orgId);
            return null;
        }

        /* 查询营销活动机构表,判断是否存在当前商户管理机构 */
        MfdMcListInfoInObj mfdMcListInfoInObj = new MfdMcListInfoInObj();
        mfdMcListInfoInObj.setInstId(instId);
        mfdMcListInfoInObj.setOrgId(orgId);
        McDetailInfoMapper mcDetailInfoMapper = new McDetailInfoMapperImpl();
        List<TMMcMchntFeeDiscountInfo> tmMcMchntFeeDiscountInfoList = mcDetailInfoMapper.selectMfdMcDetailInfoForComboPayment(mfdMcListInfoInObj);
        if (null == tmMcMchntFeeDiscountInfoList || tmMcMchntFeeDiscountInfoList.isEmpty()) {
            rglog.info("未获取到法人机构<{}>的商户<{}>所在机构<{}>的支持新增商户的商户手续费优惠类营销活动信息,该商户无法任何商户手续费优惠活动!", instId, mchntNo, orgId);
            return null;
        }

        boolean notDistinguishMiddleOfMonth;
        //判断机构是否设置了区分新商户是15号之前还是之后入驻
        MompSysParamMapper mompSysParamMapper = new MompSysParamMapperImpl();
        SysParam sysParam = mompSysParamMapper.getSysParamInfoBuyPrimaryKey(globalInstId, MOMP_DISTINGUISH_MIDDLE_OF_MONTH, MOMP_DISTINGUISH_MIDDLE_OF_MONTH);
        //如果没有配置（为空）时或者配置的为区分15号时，则进行区分15号之前之后的处理
        if (null != sysParam && CommonConstant.NO.equals(sysParam.getParamValue())) {
            rglog.info("机构<{}>配置了新商户不区分15号之前之后入驻", globalInstId);
            notDistinguishMiddleOfMonth = true;
        } else {
            rglog.info("机构<{}> 新商户区分15号之前之后入驻", globalInstId);
            notDistinguishMiddleOfMonth = false;
        }

        //正在进行的手续费优惠活动只能是一个
        int size = tmMcMchntFeeDiscountInfoList.size();
        rglog.info("查询到机构<{}>的商户<{}>有<{}>条正在进行的支持新增商户的手续费优惠活动，还需继续判断", instId, mchntNo, size);

        //商户入驻时间
        String mchntExpandTime = mchntBaseInfo.getMchntExpandTime();//格式为：yyyy-MM-dd HH:mm:ss.SSS
        String mchntExpandDate = mchntExpandTime.substring(0, 4) + mchntExpandTime.substring(5, 7) + mchntExpandTime.substring(8, 10);

        List<TMMcMchntFeeDiscountInfo> tmMcMchntFeeDiscountInfoList1 = new ArrayList<>();

        /* 判断商户入驻日期是否在营销活动期间 */
        for (TMMcMchntFeeDiscountInfo tmMcMchntFeeDiscountInfo : tmMcMchntFeeDiscountInfoList) {

            //判断商户是否在营销活动起止日期内入驻
            int returnCode = MompDateUtil.checkDateRange(mchntExpandDate, tmMcMchntFeeDiscountInfo.getMcStartDate(), tmMcMchntFeeDiscountInfo.getMcEndDate());
            if (CommonConstant.PROCESS_SUCCESS != returnCode) {
                rglog.info("法人机构<{}>的商户<{}>的入住日期<{}>并未在营销活动<{}>的起止日期<{}>~<{}>内,判断流程继续!", instId, mchntNo, mchntExpandDate, tmMcMchntFeeDiscountInfo.getMcNo(), tmMcMchntFeeDiscountInfo.getMcStartDate(), tmMcMchntFeeDiscountInfo.getMcEndDate());
                continue;
            }
            //判断当前日期是否已超过该商户入驻日期+优惠月份数(即是否在免手续费周期内)
            if (!checkNewMchntAvailability(mchntNo, tmMcMchntFeeDiscountInfo, mchntExpandDate, notDistinguishMiddleOfMonth)) {
                rglog.info("法人机构<{}>的商户<{}>的入驻日期<{}>并未在营销活动<{}>的起止日期<{}>~<{}>内,该商户免手续费周期内!", instId, mchntNo, mchntExpandDate, tmMcMchntFeeDiscountInfo.getMcNo(), tmMcMchntFeeDiscountInfo.getMcStartDate(), tmMcMchntFeeDiscountInfo.getMcEndDate());
                continue;
            }

            /* 判断当前支持新增商户的活动是否指定了商圈，如果指定了商圈，判断当前商户是否在商圈中，如果不在，则当前商户不能参加当前新商户的营销活动 */
            //查询营销活动商户信息表，判断活动是否设置了限定了指定的商圈进行参加
            List<TMMcMchntInfo> tMMcMchntInfoList = selectMcMchntInfoListByMcNo(globalInstId, tmMcMchntFeeDiscountInfo.getMcNo(), CommonConstant.MCHNT_RANGE_TYPE_AREA);
            String mchntArea = mchntBaseInfo.getMchntArea();

            if (null != tMMcMchntInfoList && !tMMcMchntInfoList.isEmpty()) {
                for (TMMcMchntInfo tMMcMchntInfo : tMMcMchntInfoList) {
                    String mcMchntArea = tMMcMchntInfo.getMchntNo();
                    if (mcMchntArea.equals(mchntArea)) {
                        tmMcMchntFeeDiscountInfoList1.add(tmMcMchntFeeDiscountInfo);
                        rglog.info("营销活动<{}>限定了参与活动的商圈<{}>，当前商户所属商圈<{}>,当前活动允许参加!", tmMcMchntFeeDiscountInfo.getMcNo(), tMMcMchntInfo.getMchntNo(), mchntArea);
                    } else {
                        rglog.info("营销活动<{}>限定了参与活动的商圈<{}>，当前商户所属商圈<{}>,当前活动不允许当前商户参加!", tmMcMchntFeeDiscountInfo.getMcNo(), tMMcMchntInfo.getMchntNo(), mchntArea);
                    }
                }
            } else {
                //如果活动未指定参与的商圈，则任何新增商户都可参与
                tmMcMchntFeeDiscountInfoList1.add(tmMcMchntFeeDiscountInfo);
                rglog.info("营销活动<{}>未限定参与活动的商圈,当前商户可以参加当前活动!", tmMcMchntFeeDiscountInfo.getMcNo());
            }
        }

        List<TMMcMchntFeeDiscountInfo> tmMcMchntFeeDiscountInfoAfterJudgeMchntNature = new ArrayList<>();
        /* 判断活动是否区分商户性质参加 */
        JudgeMcDiscriminateMchntNature(tmMcMchntFeeDiscountInfoList1, tmMcMchntFeeDiscountInfoAfterJudgeMchntNature, mchntBaseInfo);

        /* 选取支持免手续费优惠时间最长的营销活动免手续费  在做交易的时候使用的是免手续费周期最长的*/
        TMMcMchntFeeDiscountInfo tmMcMchntFeeDiscountInfo;
        if (CommonConstant.ZERO < tmMcMchntFeeDiscountInfoAfterJudgeMchntNature.size()) {
            tmMcMchntFeeDiscountInfo = tmMcMchntFeeDiscountInfoAfterJudgeMchntNature.stream().max(Comparator.comparing(TMMcMchntFeeDiscountInfo::getRemark1)).get();
            //选取到免手续费时间最长的营销活动
            rglog.info("法人机构<{}>的商户<{}>的入住日期<{}>在营销活动<{}>的起止日期<{}>~<{}>内,且免手续费周期<{}>,时间最长！",
                    globalInstId, mchntNo, mchntExpandDate, tmMcMchntFeeDiscountInfo.getMcNo(), tmMcMchntFeeDiscountInfo.getMcStartDate(), tmMcMchntFeeDiscountInfo.getMcEndDate(), tmMcMchntFeeDiscountInfo.getNewMchntPeriod());
        } else {
            rglog.info("法人机构<{}>的商户<{}>未找到适合的支持新增商户的营销活动,该商户任何商户手续费优惠活动!", globalInstId, mchntNo);
            return null;
        }

        rglog.info("机构<{}>的商户<{}>有正在进行的手续费优惠活动<{}>,新商户免手续费", instId, mchntNo, tmMcMchntFeeDiscountInfo.getMcNo());

        StatisticsStatementQueryRespInfo statisticsStatementQueryRespInfo = new StatisticsStatementQueryRespInfo();
        statisticsStatementQueryRespInfo.setMcNo(tmMcMchntFeeDiscountInfo.getMcNo());
        statisticsStatementQueryRespInfo.setFeeLimit(tmMcMchntFeeDiscountInfo.getNewMchntAmountLimit());
        statisticsStatementQueryRespInfo.setInitStatData(tmMcMchntFeeDiscountInfo.getInitStatData());
        statisticsStatementQueryRespInfo.setMrctDisUpLmtVal(tmMcMchntFeeDiscountInfo.getNewMchntAmountLimit());
        //设置为新增商户
        statisticsStatementQueryRespInfo.setNewMchntFlag(CommonConstant.MCHNT_NEW_FLAG);
        //此時有支持符合条件的新增商户手续费优惠活动且商户没有做过交易 暂时将周期开始试驾设置成今天
        statisticsStatementQueryRespInfo.setPeriodStartDate(globalTxnDate);
        return statisticsStatementQueryRespInfo;
    }

    /**
     * 商户手续费优惠活动查询营销活动商户信息
     *
     * @return cc.rengu.igas.momp.common.entity.TMMcMchntInfo 商户基本信息表T_B_MCHNT_BASE_INFO
     * @throws Exception 异常信息
     * @author liujinan
     * @date 2021/2/26 10:13
     */
    private List<TMMcMchntInfo> selectMcMchntInfoListByMcNo(String instId, String mcNo, String mchntType) throws Exception {

        TMMcMchntInfo mcMchntInfo = new TMMcMchntInfo();
        mcMchntInfo.setInstId(instId);
        mcMchntInfo.setMcNo(mcNo);
        mcMchntInfo.setMchntType(mchntType);

        McMchntInfoMapper mcMchntInfoMapper = new McMchntInfoMapperImpl();
        return mcMchntInfoMapper.selectMcMchntInfoListByMcNo(instId, mcNo, mchntType);
    }

    /**
     * 判断活动是否区分商户性质的才能参加
     *
     * @author liujinan
     * @date 2021/3/21 10:13
     */
    private void JudgeMcDiscriminateMchntNature(List<TMMcMchntFeeDiscountInfo> inputTmMcMchntFeeDiscountInfo, List<TMMcMchntFeeDiscountInfo> tmMcMchntFeeDiscountInfoAfterJudgeMchntNature, TBMchntBaseInfo mchntBaseInfo) throws Exception {
        if (CommonConstant.ZERO < inputTmMcMchntFeeDiscountInfo.size()) {
            if (CommonConstant.INST_ID_815.equals(globalInstId)) {
                JudgeMcDiscriminateMchntNature815(inputTmMcMchntFeeDiscountInfo, tmMcMchntFeeDiscountInfoAfterJudgeMchntNature, mchntBaseInfo);
            } else {
                JudgeMcDiscriminateMchntNatureOthers(inputTmMcMchntFeeDiscountInfo, tmMcMchntFeeDiscountInfoAfterJudgeMchntNature, mchntBaseInfo);
            }
        } else {
            rglog.info("法人机构<{}>的商户<{}>未找到适合的支持新增商户的营销活动,该商户无法享受任何商户手续费优惠活动!", globalInstId, mchntBaseInfo.getMchntNo());
        }
    }

    /**
     * 判断活动是否区分商户性质的才能参加--815济宁行处理流程
     *
     * @author liujinan
     * @date 2021/5/12 10:13
     */
    private void JudgeMcDiscriminateMchntNature815(List<TMMcMchntFeeDiscountInfo> inputTmMcMchntFeeDiscountInfo, List<TMMcMchntFeeDiscountInfo> tmMcMchntFeeDiscountInfoAfterJudgeMchntNature, TBMchntBaseInfo mchntBaseInfo) throws Exception {
        //当前商户号
        String mchntNo = mchntBaseInfo.getMchntNo();
        //当前商户的性质 01-小微商户 02-个体工商户 03-企业 04-党政 05-机关及事业单位 99-其他组织
        String mchntNature = mchntBaseInfo.getMchntNature();
        rglog.info("当前商户<{}> 企业性质为<{}> 01-小微商户 02-个体工商户 03-企业 04-党政 05-机关及事业单位 99-其他组织", mchntNo, mchntNature);

        //查询商户的结算账户
        rglog.info("查询商户<{}> 的结算账户信息!", mchntBaseInfo.getMchntNo());
        /*商户结算信息正式表*/
        McMchntAcctInfoMapper mcMchntAcctInfoMapper = new McMchntAcctInfoMapperImpl();
        MchntAcctInfo mchntAcctInfo = mcMchntAcctInfoMapper.selectMchntAcctInfoByPrimaryKey(globalInstId, mchntNo, "*", FundTypeEnum.SETTLE_TYPE.getFundCode());

        /* 判断活动是否区分商户性质参加，如果区分，则判断当前商户是否符合条件 */
        for (TMMcMchntFeeDiscountInfo tmMcMchntFeeDiscountInfo : inputTmMcMchntFeeDiscountInfo) {
            //当前活动支持的商户类型
            String avySprtMrctTypString = tmMcMchntFeeDiscountInfo.getavySprtMrctTyp();
            if (null == avySprtMrctTypString ||
                    CommonConstant.EMPTY_STRING.equals(avySprtMrctTypString) ||
                    CommonConstant.SUPPORT_ALLTYPES_MCHNT.equals(avySprtMrctTypString)) {
                rglog.info("营销活动<{}> 支持所有类型的商户参加,无需校验当前商户的性质", tmMcMchntFeeDiscountInfo.getMcNo());
                tmMcMchntFeeDiscountInfoAfterJudgeMchntNature.add(tmMcMchntFeeDiscountInfo);
            } else {
                //当前活动支持的商户性质 小微商户|个体工商户|企业|党政|机关及事业单位|其他组织
                String[] avySprtMrctTyp = avySprtMrctTypString.split(CommonConstant.VERTICAL_LINE);
                if (CommonConstant.SIX != avySprtMrctTyp.length) {
                    rglog.error("营销活动<{}> 配置的支持参加的商户类型异常,商户无法参加本活动！", tmMcMchntFeeDiscountInfo.getMcNo());
                    continue;
                }

                String settleAcctType = "";
                if (null != mchntAcctInfo) {
                    //结算账户类型
                    settleAcctType = mchntAcctInfo.getSettleAcctType();
                    if (AcctTypeEnum.OWN_CORPORATE_ACCOUNT.getAcctType().equals(settleAcctType) ||
                            AcctTypeEnum.OTHER_CORPORATE_ACCOUNT.getAcctType().equals(settleAcctType)) {
                        rglog.info("当前商户<{}> 结算账户类型<{}> 结算账户为对公户，对公户需要参与针对企业商户的营销活动，判断当前营销活动是否满足!", mchntNo, settleAcctType);
                        if (!CommonConstant.ONE_COMMON_CONSTANT.equals(avySprtMrctTyp[2])) {
                            rglog.error("当前活动<{}> 不支持企业类型商户参与活动!", tmMcMchntFeeDiscountInfo.getMcNo());
                        } else {
                            rglog.info("当前活动<{}> 支持企业类型商户参与活动!", tmMcMchntFeeDiscountInfo.getMcNo());
                            tmMcMchntFeeDiscountInfoAfterJudgeMchntNature.add(tmMcMchntFeeDiscountInfo);
                        }
                    } else if (AcctTypeEnum.OWN_DEBIT.getAcctType().equals(settleAcctType) ||
                            AcctTypeEnum.OWN_CREDIT.getAcctType().equals(settleAcctType) ||
                            AcctTypeEnum.OWN_BANK_BOOK.getAcctType().equals(settleAcctType) ||
                            AcctTypeEnum.OTHER_DEBIT.getAcctType().equals(settleAcctType) ||
                            AcctTypeEnum.OTHER_CREDIT.getAcctType().equals(settleAcctType) ||
                            AcctTypeEnum.OTHER_BANK_BOOK.getAcctType().equals(settleAcctType)) {
                        rglog.info("当前商户<{}> 结算账户类型<{}> 结算账户为对私户，小微商户参与小微商户的活动，其他类型的商户参与个体商户的营销活动!", mchntNo, settleAcctType);
                        if ("01".equals(mchntNature)) {
                            //判断当前商户是否支持小微企业的营销活动
                            if (!CommonConstant.ONE_COMMON_CONSTANT.equals(avySprtMrctTyp[0])) {
                                rglog.error("当前活动<{}> 不支持小微类型商户参与活动!", tmMcMchntFeeDiscountInfo.getMcNo());
                            } else {
                                rglog.info("当前活动<{}> 支持小微类型商户参与活动!", tmMcMchntFeeDiscountInfo.getMcNo());
                                tmMcMchntFeeDiscountInfoAfterJudgeMchntNature.add(tmMcMchntFeeDiscountInfo);
                            }
                        } else {
                            //判断当前商户是否支持个体的营销活动
                            if (!CommonConstant.ONE_COMMON_CONSTANT.equals(avySprtMrctTyp[1])) {
                                rglog.error("当前活动<{}> 不支持个体类型商户参与活动!", tmMcMchntFeeDiscountInfo.getMcNo());
                            } else {
                                rglog.info("当前活动<{}> 支持个体类型商户参与活动!", tmMcMchntFeeDiscountInfo.getMcNo());
                                tmMcMchntFeeDiscountInfoAfterJudgeMchntNature.add(tmMcMchntFeeDiscountInfo);
                            }
                        }
                    } else {
                        rglog.error("商户<{}> 结算账户类型<{}> 不是对公户也不是对私户，不能参加当前活动!", tmMcMchntFeeDiscountInfo.getMcNo(), settleAcctType);
                    }
                } else {
                    rglog.error("商户<{}> 结算账户信息查询异常，无法判断是否能够参与营销活动!", mchntBaseInfo.getMchntNo());
                }
            }
        }
        rglog.info("判断各活动是否区分商户性质完成，流程继续！");
    }

    /**
     * 判断活动是否区分商户性质的才能参加--通用处理流程
     *
     * @author liujinan
     * @date 2021/5/12 10:13
     */
    private void JudgeMcDiscriminateMchntNatureOthers(List<TMMcMchntFeeDiscountInfo> inputTmMcMchntFeeDiscountInfo, List<TMMcMchntFeeDiscountInfo> tmMcMchntFeeDiscountInfoAfterJudgeMchntNature, TBMchntBaseInfo mchntBaseInfo) throws Exception {
        //当前商户号
        String mchntNo = mchntBaseInfo.getMchntNo();
        //当前商户的性质 01-小微商户 02-个体工商户 03-企业 04-党政 05-机关及事业单位 99-其他组织
        String mchntNature = mchntBaseInfo.getMchntNature();
        rglog.info("当前商户<{}> 企业性质为<{}> 01-小微商户 02-个体工商户 03-企业 04-党政 05-机关及事业单位 99-其他组织", mchntNo, mchntNature);

        /* 判断活动是否区分商户性质参加，如果区分，则判断当前商户是否符合条件 */
        for (TMMcMchntFeeDiscountInfo tmMcMchntFeeDiscountInfo : inputTmMcMchntFeeDiscountInfo) {
            //当前活动支持的商户类型
            String avySprtMrctTypString = tmMcMchntFeeDiscountInfo.getavySprtMrctTyp();
            if (null == avySprtMrctTypString ||
                    CommonConstant.EMPTY_STRING.equals(avySprtMrctTypString) ||
                    CommonConstant.SUPPORT_ALLTYPES_MCHNT.equals(avySprtMrctTypString)) {
                rglog.info("营销活动<{}> 支持所有类型的商户参加,无需校验当前商户的性质", tmMcMchntFeeDiscountInfo.getMcNo());
                tmMcMchntFeeDiscountInfoAfterJudgeMchntNature.add(tmMcMchntFeeDiscountInfo);
            } else {
                //当前活动支持的商户性质 小微商户|个体工商户|企业|党政|机关及事业单位|其他组织
                String[] avySprtMrctTyp = avySprtMrctTypString.split(CommonConstant.VERTICAL_LINE);

                if (CommonConstant.SIX != avySprtMrctTyp.length) {
                    rglog.error("营销活动<{}> 配置的支持参加的商户类型异常,商户无法参加本活动！", tmMcMchntFeeDiscountInfo.getMcNo());
                    continue;
                }

                switch (mchntNature) {
                    case "01":
                        if (CommonConstant.ONE_COMMON_CONSTANT.equals(avySprtMrctTyp[0])) {
                            rglog.info("营销活动<{}>限定商户性质,允许小微商户参与", tmMcMchntFeeDiscountInfo.getMcNo());
                            tmMcMchntFeeDiscountInfoAfterJudgeMchntNature.add(tmMcMchntFeeDiscountInfo);
                        } else {
                            rglog.info("营销活动<{}>限定商户性质,不允许小微商户参与", tmMcMchntFeeDiscountInfo.getMcNo());
                        }
                        break;
                    case "02":
                        if (CommonConstant.ONE_COMMON_CONSTANT.equals(avySprtMrctTyp[1])) {
                            rglog.info("营销活动<{}>限定商户性质,允许个体工商户参与", tmMcMchntFeeDiscountInfo.getMcNo());
                            tmMcMchntFeeDiscountInfoAfterJudgeMchntNature.add(tmMcMchntFeeDiscountInfo);
                        } else {
                            rglog.info("营销活动<{}>限定商户性质,不允许个体工商户参与", tmMcMchntFeeDiscountInfo.getMcNo());
                        }
                        break;
                    case "03":
                        if (CommonConstant.ONE_COMMON_CONSTANT.equals(avySprtMrctTyp[2])) {
                            rglog.info("营销活动<{}>限定商户性质,允许企业商户参与", tmMcMchntFeeDiscountInfo.getMcNo());
                            tmMcMchntFeeDiscountInfoAfterJudgeMchntNature.add(tmMcMchntFeeDiscountInfo);
                        } else {
                            rglog.info("营销活动<{}>限定商户性质,不允许企业商户参与", tmMcMchntFeeDiscountInfo.getMcNo());
                        }
                        break;
                    case "04":
                        if (CommonConstant.ONE_COMMON_CONSTANT.equals(avySprtMrctTyp[3])) {
                            rglog.info("营销活动<{}>限定商户性质,允许党政商户参与", tmMcMchntFeeDiscountInfo.getMcNo());
                            tmMcMchntFeeDiscountInfoAfterJudgeMchntNature.add(tmMcMchntFeeDiscountInfo);
                        } else {
                            rglog.info("营销活动<{}>限定商户性质,不允许党政商户参与", tmMcMchntFeeDiscountInfo.getMcNo());
                        }
                        break;
                    case "05":
                        if (CommonConstant.ONE_COMMON_CONSTANT.equals(avySprtMrctTyp[4])) {
                            rglog.info("营销活动<{}>限定商户性质,允许机关及事业单位商户参与", tmMcMchntFeeDiscountInfo.getMcNo());
                            tmMcMchntFeeDiscountInfoAfterJudgeMchntNature.add(tmMcMchntFeeDiscountInfo);
                        } else {
                            rglog.info("营销活动<{}>限定商户性质,不允许机关及事业单位商户参与", tmMcMchntFeeDiscountInfo.getMcNo());
                        }
                        break;
                    case "99":
                        if (CommonConstant.ONE_COMMON_CONSTANT.equals(avySprtMrctTyp[5])) {
                            rglog.info("营销活动<{}>限定商户性质,允许其他组织商户参与", tmMcMchntFeeDiscountInfo.getMcNo());
                            tmMcMchntFeeDiscountInfoAfterJudgeMchntNature.add(tmMcMchntFeeDiscountInfo);
                        } else {
                            rglog.info("营销活动<{}>限定商户性质,不允许其他组织商户参与", tmMcMchntFeeDiscountInfo.getMcNo());
                        }
                        break;
                    default:
                        rglog.error("当前活动<{}>限定商户性质，但当前商户的性质异常 mchntNature: <{}>", tmMcMchntFeeDiscountInfo.getMcNo(), mchntNature);
                        break;
                }
            }
        }
        rglog.info("判断各活动是否区分商户性质完成，流程继续！");
    }

    /**
     * 校验商户是否重复入网商户
     *
     * @param mchntNo         商户编号
     * @param mchntExpandTime 商户入驻时间
     * @return
     * @throws Exception
     * @author liujinan
     * @since 2021/5/28 09:06
     */
    private boolean checkMchntRepeatFlag(String mchntNo, String mchntExpandTime) throws Exception {
        boolean repeatFlag = false;
        /* 东营行校验重复入网 */
        if (INST_ID_DY.equals(globalInstId)) {
            rglog.info("根据机构号<{}>商户<{}>入驻时间<{}>校验是否存在注销后一年内重复入网商户", globalInstId, mchntNo, mchntExpandTime);
            //格式化商户入驻日期
            String mchntExpandDate = mchntExpandTime.replaceAll("-", "").substring(0, 8);
            //获取一年前日期
            String lastYearDate = MompDateUtil.getFutureMonDay(mchntExpandDate, -12);
            //获取商户基本信息,可能存在多个结算账号
            List<TBMchntSignInfo> tbMchntSignList = selectMchntSignInfoByPrimaryPK(globalInstId, mchntNo);
            rglog.info("查询商户<{}>签约信息size=<{}>", mchntNo, tbMchntSignList.size());
            for (TBMchntSignInfo tbMchntSignInfo : tbMchntSignList) {
                //查询历史签约商户号
                List<TBMchntSignInfo> signList = selectRepeatMchntBySignInfoForDY(globalInstId, mchntNo, tbMchntSignInfo.getArtifCertNo(), tbMchntSignInfo.getLicenceCode(), tbMchntSignInfo.getSettleAcctNo());
                if (signList != null && !signList.isEmpty()) {
                    rglog.info("查询商户<{}>证件信息历史入驻信息size=<{}>", mchntNo, signList.size());
                    for (TBMchntSignInfo signInfo : signList) {
                        String cancelMchntNo = signInfo.getMchntNo();
                        if (!cancelMchntNo.equals(mchntNo)) {
                            String expandTime = signInfo.getExpandTime();
                            String lastAuditTime = signInfo.getLastAuditTime();
                            rglog.info("商户<{}>入驻时间(一年前)<{}>,检查注销商户[{}],入驻时间为[{}],注销时间为[{}],", mchntNo, lastYearDate, cancelMchntNo, expandTime, lastAuditTime);
                            if (!StringUtil.isNullorEmpty(lastAuditTime)) {
                                //格式化商户注销日期
                                String cancelDate = DateUtil.dateStringFormatConvert(lastAuditTime.substring(0, 10), "yyyy-MM-dd", "yyyyMMdd");
                                //判断注销商户注销后是否一年内入网
                                if (DateUtil.compareDate(cancelDate, lastYearDate) > 0) {
                                    //查询商户营销统计商户表累计优惠额度
                                    TMStatMfdMchnt tmStatMfdMchnt = selectMchntFeeTotalAmtMchntStatistics(globalInstId, cancelMchntNo);
                                    if (tmStatMfdMchnt != null) {
                                        String totalAmtAcc = tmStatMfdMchnt.getTotalAmtAcc();
                                        //超过额度，判定为重复入网
                                        if (!StringUtil.isNullorEmpty(totalAmtAcc) && AmountUtil.compare(totalAmtAcc, DISCOUNT_AMOUNT) == 1) {
                                            repeatFlag = true;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        return repeatFlag;
    }

    /**
     * 通过商户编号从内管商户签约信息表查询商户签约信息
     *
     * @param globalInstId 法人机构号
     * @param mchntNo      商户编号
     * @return cc.rengu.igas.momp.common.entity.TBMchntBaseInfo 商户基本信息表T_B_MCHNT_BASE_INFO
     * @throws Exception 异常信息
     * @author liujinan
     * @since 2021/5/28 09:06
     */
    private List<TBMchntSignInfo> selectMchntSignInfoByPrimaryPK(String globalInstId, String mchntNo) throws Exception {
        MchntInfoMapper mchntInfoMapper = new MchntInfoMapperImpl();
        return mchntInfoMapper.selectMchntSignInfoByPrimaryPK(globalInstId, mchntNo);
    }

    /**
     * 东营行商户重复入驻校验
     *
     * @param instId       成员行号
     * @param mchntNo      商户号
     * @param artifCertNo  证件号码
     * @param licenceCode  营业执照
     * @param settleAcctNo 结算账户
     * @return
     * @throws Exception
     */
    private List<TBMchntSignInfo> selectRepeatMchntBySignInfoForDY(String instId, String mchntNo, String artifCertNo, String licenceCode, String settleAcctNo) throws Exception {
        MchntInfoMapper mchntInfoMapper = new MchntInfoMapperImpl();
        return mchntInfoMapper.selectRepeatMchntBySignInfo(instId, mchntNo, artifCertNo, licenceCode, settleAcctNo);
    }

    /**
     * 使用主键查询手续费减免活动商户统计表累计优惠金额数据库操作接口实现
     *
     * @param instId  法人机构号
     * @param mchntNo 商户编号
     * @return cc.rengu.igas.momp.common.entity.TMStatMfdMchnt 手续费减免活动商户统计表
     * @throws Exception 异常信息
     * @author liujinan
     * @date 2021/5/28 14:55
     */
    private TMStatMfdMchnt selectMchntFeeTotalAmtMchntStatistics(String instId, String mchntNo) throws Exception {
        TMStatMfdMchntMapper tmStatMfdMchntMapper = new TMStatMfdMchntMapperImpl();
        return tmStatMfdMchntMapper.selectMchntFeeTotalAmtMchntStatistics(instId, mchntNo);
    }

    /**
     * 使用主键查询统计信息备份表最新一条数据
     *
     * @param instId
     * @param statType
     * @param statPrimaryKey
     * @return cc.rengu.igas.momp.common.entity.TMStatMfdPeriod
     * @throws Exception
     * @author liujinan
     * @date 2021/7/9
     */
    private TMStatBak selectTMStatBakByStatPrimaryKey(String instId, String statType, String statPrimaryKey) throws Exception {

        TMStatBakMapper tmStatBakMapper = new TMStatBakMapperImpl();
        return tmStatBakMapper.selectTMStatBakByStatPrimaryKey(instId, statType, statPrimaryKey);
    }

    /**
     * 使用主键取手续费减免活动商户单日统计表单条数据
     *
     * @param instId    法人机构号
     * @param mcNo      营销活动编号
     * @param ruleIndex 规则顺序号
     * @param mchntNo   商户编号
     * @param txnDate   交易日期
     * @return cc.rengu.igas.momp.common.entity.TMStatMfdMchntDay 手续费减免活动商户单日统计表
     * @throws Exception 异常信息
     * @author liujinan
     * @since 2020/4/20 23:42
     */
    private TMStatMfdMchntDay selectMchntFeeDiscountMchntDayStatisticsByPK(String instId, String mcNo, String ruleIndex, String mchntNo, String txnDate) throws Exception {

        TMStatMfdMchntDayMapper tmStatMfdMchntDayMapper = new TMStatMfdMchntDayMapperImpl();
        return tmStatMfdMchntDayMapper.selectMchntFeeDiscountMchntDayStatisticsByPK(instId, mcNo, ruleIndex, mchntNo, txnDate);
    }

    /**
     * 手续费减免活动商户统计数据赋值
     *
     * @param tmStatMfdMchnt    手续费减免活动商户统计表
     * @param tmStatMfdMchntDay 手续费减免活动商户单日统计表
     * @author Jinan Liu
     * @since 2020/6/5 11:23
     */
    private void copyMchntStatMfdData(TMStatMfdMchnt tmStatMfdMchnt, TMStatMfdMchntDay tmStatMfdMchntDay) {

        /* 营销活动单日累计-总预算累计消耗笔数 */
        tmStatMfdMchnt.setTotalQtyAcc(new BigDecimal(tmStatMfdMchnt.getTotalQtyAcc()).add(new BigDecimal(tmStatMfdMchntDay.getTotalQtyAcc())).toString());
        /* 营销活动单日累计-总预算累计消耗金额 */
        tmStatMfdMchnt.setTotalAmtAcc(new BigDecimal(tmStatMfdMchnt.getTotalAmtAcc()).add(new BigDecimal(tmStatMfdMchntDay.getTotalAmtAcc())).setScale(CommonConstant.DECIMAL_SCALE_TWO, RoundingMode.HALF_UP).toString());
        /* 营销活动单日累计-总预算累计消耗笔数 */
        tmStatMfdMchnt.setTxnQtyAcc(new BigDecimal(tmStatMfdMchnt.getTxnQtyAcc()).add(new BigDecimal(tmStatMfdMchntDay.getTxnQtyAcc())).toString());
        /* 营销活动单日累计-总预算累计消耗金额 */
        tmStatMfdMchnt.setTxnAmtAcc(new BigDecimal(tmStatMfdMchnt.getTxnAmtAcc()).add(new BigDecimal(tmStatMfdMchntDay.getTxnAmtAcc())).setScale(CommonConstant.DECIMAL_SCALE_TWO, RoundingMode.HALF_UP).toString());
    }
}
